要理解的关键是list 对象没有行和列。列表对象是有序的、异构的对象序列。当你这样做时:
def createGamePlan(size, sign):
gPlan = []
row = [sign]*size
for i in range(size):
gPlan.append(row) # appends the SAME object
return gPlan
所以,考虑以下几点:
>>> a = ['foo']
>>> bar = []
>>> for _ in range(4):
... bar.append(a)
...
>>> [id(x) for x in bar]
[4534044744, 4534044744, 4534044744, 4534044744]
对象都是一样的!
>>> bar[0].append('baz')
>>> bar
[['foo', 'baz'], ['foo', 'baz'], ['foo', 'baz'], ['foo', 'baz']]
您多次创建一个包含相同对象的列表。一个解法?附加一个副本。
def createGamePlan(size, sign):
gPlan = []
row = [sign]*size
for i in range(size):
gPlan.append(row.copy()) # appends a NEW object
return gPlan
不过要小心,因为.copy 只会制作浅 副本。考虑:
>>> row = [['foo'], ['bar']]
>>> grid = []
>>> for _ in range(5):
... grid.append(row.copy())
...
>>> grid
[[['foo'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']]]
好的,膨胀!这些都是独立的对象!:
>>> [id(x) for x in grid]
[4534044616, 4534135432, 4534135560, 4534135176, 4534135688]
所以...这应该可以正常工作,不是吗?
>>> grid[0][0].append('baz')
>>> grid
[[['foo', 'baz'], ['bar']], [['foo', 'baz'], ['bar']], [['foo', 'baz'], ['bar']], [['foo', 'baz'], ['bar']], [['foo', 'baz'], ['bar']]]
发生了什么事?好吧,浅拷贝创建了新列表,但没有创建新的子列表,也就是说,它没有复制元素中包含的任何元素:
>>> [id(x) for row in grid for x in row]
[4534135048, 4534135112, 4534135048, 4534135112, 4534135048, 4534135112, 4534135048, 4534135112, 4534135048, 4534135112]
>>>
为此,您需要一个深拷贝:
>>> import copy
>>> row = [['foo'], ['bar']]
>>> grid = []
>>> for _ in range(5):
... grid.append(copy.deepcopy(row))
...
>>> grid
[[['foo'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']]]
>>> [id(x) for row in grid for x in row]
[4534135432, 4534135368, 4534135176, 4534135880, 4534136328, 4534161928, 4534135112, 4534162120, 4534162248, 4534162184]
>>> grid[0][0].append('baz')
>>> grid
[[['foo', 'baz'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']], [['foo'], ['bar']]]
>>>