Solved

Changing one cell in my 2D list changes the whole column

Asked by Zoë Achterberg · 725 views · 2 replies

Zoë Achterberg5 messages

Making a grid for a tic-tac-toe assignment:

grid = [[0] * 3] * 3
grid[0][0] = "X"
print(grid)
# [['X', 0, 0], ['X', 0, 0], ['X', 0, 0]]

I only set one cell. Why did it end up in every row?

2 replies

Inès BergerSolution

Because you do not have three rows. You have one row, listed three times.

[0] * 3 builds one list. Then [that_list] * 3 makes an outer list holding three references to the same inner list. Change it through any of them and every "row" shows the change, because they are all the same object. You can check: grid[0] is grid[1] prints True.

Build a new inner list for each row:

grid = [[0] * 3 for _ in range(3)]

The comprehension runs [0] * 3 again on every pass, so each row is its own list. The inner * 3 is fine, by the way: integers are immutable, so sharing them never causes this.

Link
Zoë Achterberg

The is check is what made it click. Fixed, and my win detection suddenly works too, which in hindsight was the same bug.

Link