我有一个定义为全局变量的矩阵:
BOARD = [
[0, 0, 3],
[2, 0, 0],
[0, 0, 0]
]
但是,在处理此矩阵时,我希望保持原样不变,而是处理副本。所以我在main函数中这样做是为了制作独立副本:
board = BOARD[:]
如预期的那样,board == BOARD
和board is BOARD
的结果分别为True
和False
。因此,当我像这样board[0] = [1, 0, 3]
进行编辑时,仅更改了board
,这很好。但是,如果我做board[0][0] = 1
,那么BOARD
也会改变,这不是我期望的。而且仍然很陌生,board is BOARD
仍然是False
。
为什么会有这种不一致的行为,以及关于如何解决该问题的任何建议?
编辑:
如果我跑步:
board = BOARD[:]
board[0] = [1, 0, 3]
board[0][0] = 2
然后BOARD
不变。
但是我只添加了单个索引进行比较。在实际程序中,我希望能够做到这一点:
board = BOARD[:]
board[0][0] = 2
但这就是BOARD
确实发生变化的地方,即使我希望它保持不变。
答案 0 :(得分:1)
我没有收到此错误。这是我的代码:
BOARD = [
[0, 0, 3],
[2, 0, 0],
[0, 0, 0]
]
board = BOARD[:]
print(board == BOARD) # prints True
board[0] = [1,0,3]
print(board == BOARD) # prints False
board[0][0] = 1
print(board == BOARD) # still prints False
在阅读AkThao的说明后,我了解发生了什么。
Python使用指针来实现列表。
例如,如果您设置了a = [1,2,3]
和b = a
。如果您随后修改b[0] = 5
,则a
也将被修改,因为a和b都是指向相同存储位置的指针。
2D列表是使用指向指针的指针(双指针)来实现的,即[p1,p2,p3]之类的指针列表。
当您执行board = BOARD[:]
时,它会创建列表的副本,但是不会更改指针(列表的元素)的实际值。因此,列表板实际上只是3个不同指针值的副本。
这就是为什么当您执行board [0] [0] = 1时,它也会同时更改BOARD的值的原因(因为board存储的实际指针未更改)。
像我一样完成board[0] = [1, 0, 3]
时,您正在更改指针的实际值,这就是为什么原始BOARD之后不会更改的原因。
答案 1 :(得分:0)
为什么BOARD
会完全改变?
BOARD和b都是引用。
编码vec = b时,将b地址分配给BOARD。因此,更改b中的数据也将“更改” BOARD。
我还尝试了每种方法来复制列表,但是一种方法成功了,
b=copy.deepcopy(BOARD)
尽管deepcopy
对于大型列表来说很耗时,您可以尝试一下。
import copy
B = [
[0, 0, 3],
[2, 0, 0],
[0, 0, 0]
]
print(B)
b=copy.deepcopy(B)
b[0][0] = 2
print(b)
print(B)
输出:
[[0, 0, 3], [2, 0, 0], [0, 0, 0]]
[[2, 0, 3], [2, 0, 0], [0, 0, 0]]
[[0, 0, 3], [2, 0, 0], [0, 0, 0]]
希望这对您有帮助!