How do I insert into a nonzero position in an empty list?

1

How can I insert a value in a nonzero position in an empty list?

Ex:

lista = []
.
.
.
lista.insert(3, 'valor')
    
asked by anonymous 18.06.2018 / 05:34

3 answers

3

Lists in Python have the size equal to the number of elements it contains - they are different from "arrays" or "vectors" - even though in some beginner texts they are presented as "vectors".

Then there is no way to insert the 3rd element into an empty list - it will always be the first element - why then would the elements in positions 0 and 1 be?

Depending on what you want to do, it may be that another data structure might be better for you than a list: you can have a dictionary and use it with numeric keys instead of string for example. And if you always use the "get" method, the unfilled positions in the dictionary will work as if they had a default value.

This is instead of a list that will have 10 elements, containing "0" by default created with:

dados = [0] * 10

You can create a dictionary, and always access it with get:

dados = {}
...
valor = dados.get(2, 0)   # nesse caso, se dados[2] não estiver definido, o get retorna 0.

If you do this, you do not have to create all the dictionary elements beforehand. Already with a list, this will always be necessary.

If the data structure you need is for numeric values, in this case, Python has true "array" s - vectors initialized with a number for each position. But except for very specialized problems, the dictionary or lists will be more practical - and if it is a numerical problem, it is better to use the numpy library than to use native Python arrays in general. (Python arrays even having "real" positions for the elements, as opposed to lists, also need to get explicit initial values - which gives the same as the lists for your question)

    
18.06.2018 / 14:45
1

You can write a function that fills empty spaces if the list does not have the appropriate size using a default value, see:

def insert_at_pos( lst, pos, val, default=None ):

    if( len(lst) > pos ):
       lst.insert( pos, val )
    else:
        for _ in range( pos - len(lst) ):
            lst.append( default )
        lst.append( val )

    return lst

Testing:

l1 = []
l2 = [ 1, 2, 3, 4, 5]
l3 = [ 'foo', 'bar' ]

print( insert_at_pos( l1, 3, 'valor') )
print( insert_at_pos( l2, 3, 'valor') )
print( insert_at_pos( l3, 3, 'valor') )

Output:

[None, None, None, 'valor']
[1, 2, 3, 'valor', 4, 5]
['foo', 'bar', None, 'valor']

Or, specifying how to fill in the blanks:

l1 = []
l2 = [ 1, 2, 3, 4, 5]
l3 = [ 'foo', 'bar' ]

print( insert_at_pos( l1, 3, 'valor', 'VAZIO' ) )
print( insert_at_pos( l2, 3, 'valor', 'VAZIO' ) )
print( insert_at_pos( l3, 3, 'valor', 'VAZIO' ) )

Output:

['VAZIO', 'VAZIO', 'VAZIO', 'valor']
[1, 2, 3, 'valor', 4, 5]
['foo', 'bar', 'VAZIO', 'valor']
    
18.06.2018 / 14:34
1

You can use a custom version of the List.

import collections
class MyList(collections.UserList):
    def insert(self, i, item):
        for _ in range(self.__len__(), i):
            self.append(None)
        super().insert(i, item)

Your code would be

lista = MyList()
lista.insert(3, 'valor')
print(list)

Resulting

  

[None, None, None, 'value']

    
18.06.2018 / 16:18