Here's innocent-looking code to create a 2×3 matrix of zeros:
>>> row = [0, 0, 0]
>>> matrix = [row for _ in range(2)]
>>> matrix
[[0, 0, 0], [0, 0, 0]]
Looks perfect. Now let's change one cell:
>>> matrix[0][0] = 99
>>> matrix
[[99, 0, 0], [99, 0, 0]] # BOTH rows changed!
We modified matrix[0][0], but matrix[1][0] changed too. What happened?
The Problem: Aliasing
When we wrote [row for _ in range(2)], we didn't create two rows. We created two references to the same row.
matrix[0] ──┐
├──► [99, 0, 0] (same list object)
matrix[1] ──┘
Every "row" in our matrix is the same object in memory. Change one, change all.
The Fix: Create New Lists
Each row must be a new list object:
>>> matrix = [[0, 0, 0] for _ in range(2)]
>>> matrix[0][0] = 99
>>> matrix
[[99, 0, 0], [0, 0, 0]] # Only first row changed ✓
Or more generally:
>>> rows, cols = 2, 3
>>> matrix = [[0 for _ in range(cols)] for _ in range(rows)]
The inner comprehension [0 for _ in range(cols)] runs fresh for each row, creating a new list each time.
Why This Trips People Up
The original code reads correctly: "make a list of row, two times."
But in Python, row is a reference. Repeating a reference doesn't copy the underlying object—it just creates more pointers to it.
Quick Diagnostic
Suspicious your matrix has this bug? Check with is:
>>> bad_matrix = [row for _ in range(2)]
>>> bad_matrix[0] is bad_matrix[1]
True # Same object! Bug confirmed.
>>> good_matrix = [[0, 0, 0] for _ in range(2)]
>>> good_matrix[0] is good_matrix[1]
False # Different objects. Safe.
The Rule
When creating nested structures with comprehensions:
Never repeat a reference. Always create fresh.
# WRONG - reuses same list
template = [0, 0, 0]
matrix = [template for _ in range(n)]
# RIGHT - creates new list each time
matrix = [[0, 0, 0] for _ in range(n)]
This applies to lists of lists, lists of dicts, lists of any mutable object.
This is adapted from my upcoming book, Zero to AI Engineer: Python Foundations.
I share excerpts like this on Substack → https://substack.com/@samuelochaba
Top comments (0)