Lists of empty lists (Python)

8

Using Python 2.7.12

I need to create a list as follows:

lista = [[],[],[],[],.........,[]]

This list must have a very large number of lists within it (so the ........). I found the following way to accomplish this:

lista = [[]]*n

Where "n" is the number of sub-lists. Only with that I get into a problem. Here is an example (with a much smaller number of sub-lists for illustration).

lista = [[]]*3
lista[0].append(1)
lista[1].append(2)
print lista

The output should be:

[[1], [2], []]

But the output of this code is:

[[1, 2], [1, 2], [1, 2]]

I have no idea what it is, nor do I know any other way to create such a list.

    
asked by anonymous 15.05.2018 / 01:31

1 answer

10

The problem of the code you tried to do:

lista = [[]]*n

It is that the object to be repeated, [] , is initialized only once, when its reference is defined and it is used in the other positions. To demonstrate this, simply scroll through the list and display the value of id :

lista = [[]]*3

for l in lista:
    print id(l)

See working at Repl.it | Ideone | GitHub GIST

The three values will be the same, as in:

47056207983464
47056207983464
47056207983464

In order to better demonstrate what happens, just check the opcode run, using the dis module:

>>> print dis.dis('[[]]*3')
  1           0 BUILD_LIST               0
              2 BUILD_LIST               1
              4 LOAD_CONST               0 (3)
              6 BINARY_MULTIPLY
              8 RETURN_VALUE

Notice that the BUILD_LIST operation is executed twice, one for the internal list and one for the external list; then the constant 3 is loaded and the multiplication between the values is done. That is, only one reference is created for the internal list, which is multiplied by 3.

To work around this problem, you can use list comprehension :

lista = [[] for _ in xrange(n)]

See working at Repl.it | Ideone | GitHub GIST

Thus,% w / o% distinct references are defined.

  

For the same solution in Python 3, just replace the n function with xrange .

This happens even with all the mutable Python types. For example, if you have a class range and want to create a list of instances, you can not do:

lista = [Foo()]*3

It becomes even clearer that Foo will be instantiated only once and the created object will be multiplied by 3.

    
15.05.2018 / 01:42