Why does [[0]*3]*3 break?
Multiplying a list repeats the reference, not the object. [[0]*3]*3 builds one inner list and points at it three times, so writing to one row writes to all of them. Use a comprehension — [[0]*3 for _ in range(3)] — which evaluates the inner expression once per row.
Overview
What multiplication actually does
[x] * 3 builds a list holding the same reference three times. For immutable contents that is invisible — [0] * 3 is fine, because you can never mutate a 0. For a mutable inner object it is a trap, because all three names lead to one object.
The tell is that the bug only appears on write. Building and printing the grid looks perfect; the first assignment to a cell is when it falls apart.
Step through it
What to watch
- All three rows share one address in the broken version.
- One write appears in three places — nothing was copied.
- The comprehension produces three distinct objects.
Say this out loud
"List multiplication copies references. There's one inner list and three pointers to it. A comprehension builds a fresh row each time, which is what you want."