Как правильно клонировать 2D-массив? - PullRequest
1 голос
/ 25 января 2020

я новичок в python, и мой первый проект - написать код tictactoe.

Итак, когда я пытаюсь написать метод toString, я столкнулся с проблемой с 2 ​​Dimensional.

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 () тоже не работал.

Ответы [ 3 ]

2 голосов
/ 25 января 2020

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)))

Приведенный выше код генерирует следующие отпечатки, обратите внимание, что адрес может меняться от запуска к запуску, но он должен быть одинаковым для списков A и 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
2 голосов
/ 25 января 2020

Использовать copy.deepcopy ()

from copy import deepcopy

board = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
binit = deepcopy(board)
...
0 голосов
/ 25 января 2020

Вы можете использовать copy.deepcopy для клонирования доски.

...