2
array1 = [[0]*4]*4

array2 = [[0,0,0,0]]*4

array3 = [[0,0,0,0],
          [0,0,0,0],
          [0,0,0,0],
          [0,0,0,0]]

array1[0][0] = 9000
array2[0][0] = 9000
array3[0][0] = 9000

In [77]: array1
Out[77]: [[9000, 0, 0, 0], 
          [9000, 0, 0, 0], 
          [9000, 0, 0, 0],
          [9000, 0, 0, 0]]

In [78]: array2
Out[78]: [[9000, 0, 0, 0],
          [9000, 0, 0, 0],
          [9000, 0, 0, 0],
          [9000, 0, 0, 0]]

In [79]: array3
Out[79]: [[9000, 0, 0, 0],
          [0, 0, 0, 0],
          [0, 0, 0, 0], 
          [0, 0, 0, 0]]

Mutating any row value mutates all row values for the shortcut methods of initialization.
The only way I can get non-mutating behavior is by writing out the whole list.
There must be a better way(?), think of the case where you want to initialize the list based on the length of a different list.

Albert Han
  • 109
  • 1
  • 2
  • 9

1 Answers1

3

Use a list comprehension.

my_list = [ [0]*4 for _ in range(4)]

Note that lists are mutable but integers are not. Thus [0]*4 behaves like you would expect, but [[0]*4]*4 'leaks' changes.

Using a list comprehension creates a new outer list each time, avoiding the problematic behavior of your example.

Efron Licht
  • 488
  • 3
  • 13