0
board = [['a']*3]*2
board[0][0] = 'b'

...then board becomes [['b','a','a'],['b','a','a']]

Is there a way to mutate it such that it becomes... ?

[['b','a','a'],['a','a','a']]?

Thanks.

anon582847382
  • 19,907
  • 5
  • 54
  • 57

3 Answers3

1

The way you are initializing your list is causing the problem.

>>> board = [['a']*3]*2
>>> board
[['a', 'a', 'a'], ['a', 'a', 'a']]
>>> board[0][0] = 'b'
>>> board
[['b', 'a', 'a'], ['b', 'a', 'a']]

vs

>>> board = [['a', 'a', 'a'], ['a', 'a', 'a']]
>>> board[0][0] = 'b'
>>> board
[['b', 'a', 'a'], ['a', 'a', 'a']]

In the first method, because of the way you are initializing it, board[0] and board[1] are the same list. This is the same reason you do not define default arguments in functions this way:

def f(a, b=[]):

as opposed to:

def f(a, b=None):
    if b = None:
        b = []
Two-Bit Alchemist
  • 17,966
  • 6
  • 47
  • 82
1

Your code is equivalent to something like this:

x = ['a', 'a', 'a']
board = [x, x]

board is just two copies of x. x, board[0], and board[1] all refer to same python object, and modifications made to any of these "three" lists are actually modifications to the same underlying list.

Try

board = [['a'] * 3 for i in range(2)]

edit: If you want to use numpy, this is a potentially "cleaner" alternative:

import numpy as np
board = np.repeat('a', 6).reshape(3, 2)
alecbz
  • 6,292
  • 4
  • 30
  • 50
0

Is there a way to mutate it such that it becomes... ?

Yes, you can try using the range() built-in function:

board = [['a'] * 3 for n in range(2)]

Demo:

board[0][0] = 'b'
print board
>>> [['b', 'a', 'a'], ['a', 'a', 'a']]

Why what you are doing doesn't work?

Because the expression

board = [['a']*3]*2

is equivalent to:

board = [['a', 'a', 'a']] * 2

There, you are creating a list of 2 lists. In fact, both lists are the same, both refers to the same object in memory.

Christian Tapia
  • 33,620
  • 7
  • 56
  • 73