0

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 Answers4

2

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)
John1024
  • 109,961
  • 14
  • 137
  • 171
1

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

dstromberg
  • 6,954
  • 1
  • 26
  • 27
0

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
FelixM
  • 1
  • 3
0

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.

JustGage
  • 1,534
  • 17
  • 20