如何正确克隆二维数组?

How to clone a 2D Array properly?

我是 python 的新手,我的第一个项目是手工编写井字游戏。

所以当我尝试编写一个“toString”方法时,我遇到了二维数组的问题,如下

board = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
binit = board[:]
for x in range(3):
    for y in range(3):
        if int(binit[x][y]) == 0:
            binit[x][y] = "_"
        elif int(binit[x][y]) == 1:
            binit[x][y] = "X"
        else:
            binit[x][y] = "O"

print(binit)
print(board)

我玩的时候得到的输出是:

ID: board 140662640260544
ID: binit 140662640580864
board: [['X', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
binit: [['X', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]

虽然董事会本身应该没有改变。

bint = board.copy() 也没用。

您可以使用 copy.deepcopy 克隆板。

Python 当一个列表被分配给另一个列表变量时使用引用传递,就像您的情况一样,因此当对 binit 进行更改时,更改发生在板地址,即板和 bint 都是内存中的相同对象。下面是一个小例子来理解这一点:

listA = [0]
listB = listA
listB.append(1)
print("List B: " + str(listB))
print("List A: " + str(listA))
print("Address of listB: " + hex(id(listB)))
print("Address of listA: " + hex(id(listA)))

以上代码生成如下打印,请注意地址可以从 运行 运行 更改,但 listA 和 listB 应该相同:

List B: [0, 1]
List A: [0, 1]
Address of listB: 0x1d146de5148
Address of listA: 0x1d146de5148

要为listB构造新对象,请使用深拷贝。深拷贝构造一个新的复合对象,然后递归地将在原始对象中找到的对象的副本插入其中。例如下面:

import copy

listA = [0]
listB = copy.deepcopy(listA)
listB.append(1)
print("List B: " + str(listB))
print("List A: " + str(listA))
print("Address of listB: " + hex(id(listB)))
print("Address of listA: " + hex(id(listA)))

以上使用深拷贝打印的示例,显示了 listB 的深拷贝地址发生了更改,并且更改仅发生在 listB 中:

List B: [0, 1]
List A: [0]
Address of listB: 0x23a95f8e288
Address of listA: 0x23a95f8e248

使用copy.deepcopy()

from copy import deepcopy

board = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
binit = deepcopy(board)
...