Why? Look they are equal, initially. You do the same operation but hey you get different structures. Why do the two methods of constructing nested lists give different results?
>>> lll=[[[[[]]*2 for a in xrange(2)] for b in xrange(2)]]
>>> ll=[[[[[]]*2]*2]*2]
>>> lll
[[[[[], []], [[], []]], [[[], []], [[], []]]]]
>>> ll
[[[[[], []], [[], []]], [[[], []], [[], []]]]]
>>> ll==lll
True
>>> ll[0][0][0][0]=1
>>> lll[0][0][0][0]=1
>>> ll==lll
False #Why?
Structure
[
[
[
[
[],
[]
],
[
[],
[]
]
],
[
[
[],
[]
],
[
[],
[]
]
]
]
]
When you use list comprehensions like that, new lists are created for each iteration.
When you multiply a list, the same reference is duplicated over and over.
When that reference is to a list, it means that the same inner list is duplicated over and over.
So, when you multiply, there is only one empty list, referenced twice by a single list, which is referenced twice by a single list, which is referenced twice by another single list, which is the only item in the final, outer list.
When you use a list comprehension, each reference is to a new, different list.
So, when you point the first item of the list containing two references to the empty list to a different object, you see the change everywhere that list is referenced. Since it’s referenced twice by a list that is itself referenced twice, you see the change in four places.
If you were to append a value to the very inner list:
You’d see that value referenced eight times:
because all the inner lists are actually the same list.
The real structure of
llisn’t what it appears to be above, but:[ ] | [ , ] \ / [ , ] \ / [ , ] \ / []The way it is displayed by Python is quite misleading.