how would I create a non destructive copy of a list using b = a[:] ?
-
You have two print statements. You should remove the first print, and just call the function instead: `insert_black_tiles(board, 2)` – bosnjak Apr 15 '14 at 00:04
-
@Lawrence my print statements are testing the function...they don't fix why board is changing (even though I made a non destructive copy) – user3496317 Apr 15 '14 at 00:07
4 Answers
Replace new_board = board[:]
with:
new_board = [x[:] for x in board]
board
is a list of mutable lists. board[:]
makes a copy of board
but does not make a copy of the mutable lists that it contains. The above code makes those copies.
Alternatively, use the copy
module (import copy
):
new_board = copy.deepcopy(board)

- 109,961
- 14
- 137
- 171
-
now it's not working for 8 (see edit). I'm only getting 6 of the tiles to change black – user3496317 Apr 15 '14 at 00:13
list_[:] does a copy of the first level list, not the 2nd level lists within it.
Two get both (all, really) levels, try copy.deepcopy(list_).

- 6,954
- 1
- 26
- 27
-
now it's not working for 8 (see edit). I'm only getting 6 of the tiles to change black – user3496317 Apr 15 '14 at 00:14
I've got it to work with
def insert_black_tiles(board, num_black_spaces):
new_board = board[:]
while num_black_spaces > 0:
a = random.randint(0,2)
b = random.randint(0,2)
c = 'black'
if new_board[a][b] != 'black':
new_board[a][b] = c
num_black_spaces -= 1
return new_board
In your version sometimes a black space get's black a second time.
edit: This is another variant with a library function:
def insert_black_tiles(board, num_black_spaces):
new_board = [x[:] for x in board]
three_by_three = [(i,j) for i in range(3) for j in range(3)]
for (a,b) in random.sample(three_by_three, 8):
new_board[a][b] = 'black'
return new_board

- 1
- 3
Although other people's answers are far better about the semantics of how the deep-vs-shallow. I would mention that it's generally better style (in my opinion) to use:
a = list(b)
rather than
a = b[:]
as it's a little more explicit.

- 1,534
- 17
- 20