1

I was looking at initialising a 2D list in python using grid = [['x']*4]*6 essentially to create a 2D list with six rows with four x's. So, I hoped it would be the same as this approach:

grid2 = [['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x']]

To check they are the same, I used print(grid == grid2), which python reports as True.

Next, I would like to assign grid[0][0] ='O' , to change the first 'x' to 'O', but I have a different outcome based on whether I initialised using the method used for grid and grid2. The grid = [['x']*4]*6 method changes the first element of each list in the 2D array, while the longer initialisation method does what I want, it changes just the x at row & column = 0. I do not understand why it is not the same? I am sure there is someone out there who can explain this to me because I am mystified by this, it might be obvious, but I cannot spot it. My test code is below: Thanks!

#change identifier names between grid and grid2 to test. i.e change grid to grid2, vice versa. See the difference in behaviour? 


grid2 = [['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x']]
grid = [['x']*4]*6

print(grid == grid2)

print(grid)
print(grid2)

print()

for r in grid:
  for c in r:
    print(c, end = " ")
  print()



grid[0][0] ='O' # This behaves differently depending on whether I use grid or grid2

print()

for r in grid:
  for c in r:
    print(c, end = " ")
  print()
MrM
  • 11
  • 1
  • Please check [here](https://stackoverflow.com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly) and [here](https://stackoverflow.com/questions/6688223/python-list-multiplication-3-makes-3-lists-which-mirror-each-other-when) – R. Marolahy Jul 14 '21 at 13:09

2 Answers2

0

This is not the same because grid initialization creates 4-elements list once and keep 6 references to this list.

grid2 is list containing 6 different lists.

You can check this using id method which provides identifier of object:

In [8]: id(grid[0])                                                                                                                                                                                                
Out[8]: 139751930768584

In [9]: id(grid[1])                                                                                                                                                                                                
Out[9]: 139751930768584

In [10]: id(grid[2])                                                                                                                                                                                               
Out[10]: 139751930768584

In [11]: id(grid[3])                                                                                                                                                                                               
Out[11]: 139751930768584

In [12]: id(grid2[0])                                                                                                                                                                                              
Out[12]: 139751930891016

In [13]: id(grid2[1])                                                                                                                                                                                              
Out[13]: 139751931146824

In [14]: id(grid2[2])                                                                                                                                                                                              
Out[14]: 139751930890376

In [15]: id(grid2[3])                                                                                                                                                                                              
Out[15]: 139751930889032

As you can see grid[0] is same list as grid[1] because it has same id but grid2[0] has different id that grid2[1] because they are different objects.

You can initialize such 2D list this way:

[['x' for j in range(4)] for i in range(6)]  
                                                                                                                              
domandinho
  • 1,260
  • 2
  • 16
  • 29
0

Unfortunately, the list multiplication approach results in each sublist actually being the same exact object. Here's one way around it:

>>> grid = [['x' for _ in range(4)] for _ in range(6)]
>>> grid[0][0] = 'o'
>>> grid
[['o', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x']]
StardustGogeta
  • 3,331
  • 2
  • 18
  • 32