2

I am new to python and my first project is to hand-code a tictactoe game.

So as I'm trying to write a "toString" method, I came across a problem with 2 Dimensional arrays, as follows

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)

the Output I get when playing is:

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

though the board itself should have been unchanged.

bint = board.copy() didn't work either.

dreamcrash
  • 47,137
  • 25
  • 94
  • 117
FunnyO
  • 383
  • 2
  • 20
  • Variable and function names should follow the `lower_case_with_underscores` style. _2D Array_ .... _2 Dimensional arrays_ Those are Python lists, not arrays, be careful. – AMC Jan 25 '20 at 22:04
  • Does this answer your question? [How to clone or copy a list?](https://stackoverflow.com/questions/2612802/how-to-clone-or-copy-a-list) – AMC Jan 25 '20 at 22:05
  • https://stackoverflow.com/q/6532881/11301900 – AMC Jan 25 '20 at 22:05
  • There are many, many more. – AMC Jan 25 '20 at 22:07

3 Answers3

2

Python uses pass by reference when a list is assigned to another list variable as in your case, so the changes are occurring at board address when the changes are being done to binit i.e. both board and bint are same objects in the memory. A small example to understand this below:

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

Above code generates prints following, please note address can change from run to run but it should be same for listA and listB:

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

To construct a new object for listB, please use deep copy. A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original. e.g below:

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

Above example using deep copy prints, which shows that with deep copy address of the listB got changed and the change happened to listB only:

List B: [0, 1]
List A: [0]
Address of listB: 0x23a95f8e288
Address of listA: 0x23a95f8e248
Nafeez Quraishi
  • 5,380
  • 2
  • 27
  • 34
2

Use copy.deepcopy()

from copy import deepcopy

board = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
binit = deepcopy(board)
...
alec_djinn
  • 10,104
  • 8
  • 46
  • 71
0

You can use copy.deepcopy to clone the board.

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61