Python list multiplication: [[...]]*3 makes 3 lists which mirror each other when modified [duplicate]
Why this is happening? I don't really understand:
>>> P = [ [()]*3 ]*3
>>> P
[[(), (), ()], [(), (), ()], [(), (), ()]]
>>> P[0][0]=1
>>> P
[[1, (), ()], [1, (), ()], [1, (), ()]]
Solution 1:
You've made 3 references to the same list.
>>> a = b = []
>>> a.append(42)
>>> b
[42]
You want to do this:
P = [[()] * 3 for x in range(3)]
Solution 2:
Lists are mutable, and multiplying a list by a number doesn't copy its elements. You can try changing it to a list comprehension, so it will evaluate [()]*3
three times, creating three different lists:
P = [ [()]*3 for i in range(3) ]
Solution 3:
You can also write it like this, which has the advantage of showing the structure [[()]*3]*3
>>> P=[i[:] for i in [[()]*3]*3]
>>> P[0][0]=1
>>> P
[[1, (), ()], [(), (), ()], [(), (), ()]
It's also slightly faster than using range. From ipython shell:
In [1]: timeit P = [ [()]*3 for i in range(3) ]
1000000 loops, best of 3: 1.41 us per loop
In [2]: timeit P=[i[:] for i in [[()]*3]*3]
1000000 loops, best of 3: 1.27 us per loop
Solution 4:
It's actually the same inner list (same reference) that is duplicated 3 times, so when you modify any one of them, you are actually modifying all of them.
So, the inner list [()]*3
produces a list of three tuples. But then this list is duplicated three times. However, in python, it's really a list of references that is being multiplied, so the reference is duplicated, but each reference still points to the same underlying list.