首页 > 解决方案 > 在制作矩阵(列表列表)的副本后,为什么对副本进行双重索引会更改原始内容但索引不会?

问题描述

我有一个定义为全局变量的矩阵:

BOARD = [
    [0, 0, 3],
    [2, 0, 0],
    [0, 0, 0]
]

但是,在操作此矩阵时,我想保持原件不变,而是在副本上工作。所以我在主函数中这样做是为了制作一个独立的副本:

board = BOARD[:]

正如预期的那样, 和 的结果分别是board == BOARD和。因此,当我像这样进行编辑时,只会更改,这很好。但是,如果我这样做了,那么也会发生变化,这不是我所期望的。更奇怪的是,仍然是。board is BOARDTrueFalseboard[0] = [1, 0, 3]boardboard[0][0] = 1BOARDboard is BOARDFalse

为什么会出现这种不一致的行为以及关于如何解决它的任何建议?

编辑:

如果我运行:

board = BOARD[:]
board[0] = [1, 0, 3]
board[0][0] = 2

然后BOARD不改变。

但我只添加了单个索引进行比较。在真正的程序中,我希望能够做到这一点:

board = BOARD[:]
board[0][0] = 2

但这就是BOARD改变的地方,即使我希望它保持不变。

标签: python-3.x

解决方案


我没有收到此错误。这是我的代码:

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 都是指向同一内存位置的指针。

二维列表是使用指向指针的指针(双指针)实现的,即像 [p1, p2, p3] 这样的指针列表。

当您这样做时board = BOARD[:],它会创建列表的副本,但不会更改指针的实际值(列表的元素)。因此,列表板本质上只是 3 个不同指针值的副本。

这就是为什么当你做 board[0][0] = 1 时,它也会改变 BOARD 的值(因为 board 存储的实际指针没有改变)。

当你board[0] = [1, 0, 3]像我一样做时,你正在改变指针的实际值,这就是为什么原来的 BOARD 之后不会改变的原因。


推荐阅读