That One Python List Bug That Wasted My Time π
Source: Dev.to
The Issue
I recently ran into a weird Python bug while solving a problem that needed a 2βD list.
The code looked correct, but the output was completely wrong. The culprit was this line:
index = [[0, 0]] * n
If youβve written Python for a while, you might expect this to create n rows, each with [0, 0], like:
[
[0, 0],
[0, 0],
[0, 0]
]
Why * Doesnβt Work Here
Python doesnβt create n separate inner lists. It creates one list [0, 0] and references it n times. All rows point to the same object.
Proof
index = [[0, 0]] * 3
index[0][0] = 7
print(index)
Output
[[7, 0], [7, 0], [7, 0]]
Changing one value changes every row because the * operator performs a shallow copy, effectively doing:
index = [same_list, same_list, same_list]
The Correct Way
Use a list comprehension to create a new inner list for each row:
index = [[0, 0] for _ in range(n)]
Quick Check
index = [[0, 0] for _ in range(3)]
index[0][0] = 7
print(index)
Output
[[7, 0], [0, 0], [0, 0]]
Now only the intended row is modified.
When * Is Actually Fine
Using * is perfectly acceptable with immutable values:
arr = [0] * 5 # perfectly fine
The problem only arises when you use it with nested mutable objects like lists.