DEV Community

Pavitha P
Pavitha P

Posted on

That One Python List Bug That Wasted My Time 😅

I recently ran into a weird Python bug while solving a problem that needed a 2D list.
Everything looked correct, but the output was completely wrong.

Turns out, it was this one line:

index = [[0, 0]] * n
Enter fullscreen mode Exit fullscreen mode

If you’ve written Python for a while, you might already know where this is going.


What I Thought This Did

I thought this would create n rows, each with [0, 0].

Something like:

[
  [0, 0],
  [0, 0],
  [0, 0]
]
Enter fullscreen mode Exit fullscreen mode

Reasonable assumption.
Totally wrong assumption.


What It Actually Does

Python doesn’t create n separate lists here.

It creates one list [0, 0]
and then repeats the reference to it n times.

So all rows point to the same object.

Here’s the proof:

index = [[0, 0]] * 3
index[0][0] = 7
print(index)
Enter fullscreen mode Exit fullscreen mode

Output:

[[7, 0], [7, 0], [7, 0]]
Enter fullscreen mode Exit fullscreen mode

I changed one value… and every row changed.
That’s when I knew something was off.


Why This Happens

The * operator does a shallow copy.

Internally, Python is basically doing:

index = [same_list, same_list, same_list]
Enter fullscreen mode Exit fullscreen mode

So modifying one row means modifying all of them.


The Fix (And the Right Way)

The correct way is using a list comprehension:

index = [[0, 0] for _ in range(n)]
Enter fullscreen mode Exit fullscreen mode

This creates new lists every time, not shared ones.

Quick check:

index = [[0, 0] for _ in range(3)]
index[0][0] = 7
print(index)
Enter fullscreen mode Exit fullscreen mode

Output:

[[7, 0], [0, 0], [0, 0]]
Enter fullscreen mode Exit fullscreen mode

Exactly what we want.


When * Is Actually Fine

Using * is totally okay with immutable values:

arr = [0] * 5   # perfectly fine
Enter fullscreen mode Exit fullscreen mode

The problem only starts when you use it with nested mutable objects like lists.

Top comments (0)