2

This is MWE of what I'm trying to do:

lis = []
# Initialize empty list
for i in range(2):
    lis.append([[0]]*2)

# First print
print lis

# Second print
print lis[0][1][0]

# Modify item
lis[0][1][0] += 1

# Third print
print lis

The first print returns the list as [[[0], [0]], [[0], [0]]] which is correct, I have a first list which is composed of several lists, each one also composed of several lists (I need this nested lists for what I'm doing). The second print returns the item in indexes 0 and 1 as 0 which is also correct. But the third print shows me the new list as:

[[[1], [1]], [[0], [0]]]

instead of:

[[[0], [1]], [[0], [0]]]

which is what I actually aimed at. What am I doing wrong?

Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
Gabriel
  • 40,504
  • 73
  • 230
  • 404
  • 3
    Also, [this vizualization](http://www.pythontutor.com/visualize.html#code=lis+%3D+%5B%5D%0A%23+Initialize+empty+list%0Afor+i+in+range(2)%3A%0A++++lis.append(%5B%5B0%5D%5D*2)%0A%0A%23+First+print%0Aprint+lis%0A%0A%23+Second+print%0Aprint+lis%5B0%5D%5B1%5D%5B0%5D%0A%0A%23+Modify+item%0Alis%5B0%5D%5B1%5D%5B0%5D+%2B%3D+1%0A%0A%23+Third+print%0Aprint+lis&mode=display&cumulative=false&heapPrimitives=false&drawParentPointers=false&textReferences=false&showOnlyOutputs=false&py=2&curInstr=0) makes it obvious why this works as it does. – Gareth Latty Jun 27 '13 at 17:36

1 Answers1

7

That is happening because both inner lists are actually copies of same object, so modifying one will affect the other one as well.

>>> l = [[0]]*2
>>> [id(x) for x in l]
[145328716, 145328716]             #same IDs
>>> l[0].append(4)
>>> l
[[0, 4], [0, 4]]

Use a list comprehension to avoid that:

>>> l = [[0] for _ in xrange(2)]
>>> [id(x) for x in l]           #Different IDs 
[145327372, 145327500]
>>> l[0].append(4)
>>> l
[[0, 4], [0]]
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504