二维数组在 Python 中无法正常工作



所以我试图在python中使用二维数组重新创建生命游戏,但我偶然发现了一个非常奇怪的错误。为了创建这个数组,我使用了这个函数:

def MakeGrid(height):
gridY = []
grid = []
for i in range(height):
gridY.append(False)
for i in range(height):
grid.append(gridY)
return(grid)

但是有一个非常奇怪的错误,如果我试图改变一个假到一个真只有1点,它改变对角线各处。下面是一个例子:

grid = MakeGrid(2) # grid is now [[False,False], [False,False]]
grid[0][0] = True #grid should be [[True, False], [False, False]], but it's actually [[True, False], [True, False]]

我真的不知道是什么原因引起的,但它真的很烦人,我真的很需要一些帮助。

这不是一个bug,而是当一次又一次地添加完全相同的列表时的预期行为。由于您将相同的列表(gridY)附加到grid中,因此它们都共享相同的内存grid内;这意味着在grid内部的任何列表中的一个元素(或多个)的更改将适用于grid内部的所有其他列表,因为它们是相同的对象.

看下面的句子:

x = [1, 2, 3]
y = []
y.append(x)
y.append(x)
y[0] == x  # True (same list contents)
y[0] is x  # Also True! (same memory, exact same list)
因此,您需要添加该列表的副本,该副本不共享相同的内存/标识,但使用.copy() 具有相同的内容。

发生的事情是grid数组在内存中存储了许多指向相同gridY部分的指针。当你改变一个指针时,整个gridY都会改变。因此,当您将gridY中的一个False更改为True时,整个gridY都会发生变化。你可以使用

def MakeGrid(height):
gridY = []
grid = []
for i in range(height):
gridY.append(False)
for i in range(height):
grid.append(gridY[:])
return(grid)

def MakeGrid(height):
gridY = []
grid = []
for i in range(height):
gridY.append(False)
for i in range(height):
grid.append(gridY.copy())
return(grid)

正如@Epsi95提到的

这是一个混叠问题。列表在python中是一个对象,这里你已经将gridY减速为一个列表对象,并且不断地更改它。通过不断将其追加到grid,您不会创建不同长度的新对象,而是多次添加相同的对象。当您尝试更改一次时,您将在整个grid

中更改它。

最新更新