Умножение списка Python: [[...]] * 3 делает 3 списка, которые зеркально отражают друг друга при изменении
Почему это происходит? Я действительно не понимаю:
>>> P = [ [()]*3 ]*3
>>> P
[[(), (), ()], [(), (), ()], [(), (), ()]]
>>> P[0][0]=1
>>> P
[[1, (), ()], [1, (), ()], [1, (), ()]]
Ответ 1
Вы сделали 3 ссылки на один и тот же список.
>>> a = b = []
>>> a.append(42)
>>> b
[42]
Вы хотите сделать это:
P = [[()] * 3 for x in range(3)]
Ответ 2
Списки изменяются, и умножение списка на число не копирует его элементы. Вы можете попробовать изменить его на понимание списка, поэтому он будет оценивать [()]*3 три раза, создавая три разных списка:
P = [ [()]*3 for i in range(3) ]
Ответ 3
Это фактически тот же самый внутренний список (та же ссылка), который дублируется 3 раза, поэтому, когда вы меняете какой-либо из них, вы на самом деле изменяете их все.
Итак, внутренний список [()]*3 создает список из трех кортежей. Но тогда этот список дублируется три раза. Однако в python это действительно список ссылок, которые умножаются, поэтому ссылка дублируется, но каждая ссылка все еще указывает на один и тот же базовый список.
Ответ 4
Вы также можете записать его так, что имеет преимущество при отображении структуры [[()]*3]*3
>>> P=[i[:] for i in [[()]*3]*3]
>>> P[0][0]=1
>>> P
[[1, (), ()], [(), (), ()], [(), (), ()]
Он также немного быстрее, чем использование диапазона. Из оболочки ipython:
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