BugHunt

Changing one row of a 2D list changes them all

[[0] * cols] * rows repeats a reference to one inner list. Every row is the same object, so one assignment shows up everywhere.

PythonMutation and copying bugs

What it means

Multiplying a list copies references, not values. For numbers that is harmless, because numbers cannot be changed in place, but for an inner list it means grid[0] and grid[1] are one list seen through two names.

Common causes

1. Building a grid with *

The inner list is created once and shared.

Breaks

grid = [[0] * 3] * 3
grid[0][0] = 1   # every row changes

Works

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

2. Repeating a dict or list default

Same trap with any mutable value.

Breaks

rows = [{}] * 5

Works

rows = [{} for _ in range(5)]

3. Copying a grid with a shallow copy

copy() and [:] copy the outer list only.

Breaks

backup = grid[:]

Works

import copy
backup = copy.deepcopy(grid)

How to find it in your own code

Build each inner list separately with a comprehension. When a change appears in several places at once, print id() of the parts: matching ids mean shared objects.

Still not sure why yours breaks?

Paste it into the visualizer and watch it run line by line, with every variable at every step. Free, and it runs in your browser.

Other common errors