"Shared Reference" Python

Python is a powerful and flexible language, but every now and then, it surprises you with quirks that can lead to bugs if you're not careful. One such quirk is the shared reference issue with mutable objects like lists. Let’s explore it in simple terms.


The Problem: Multiplying Lists

When you create a list and multiply it to initialize multiple sublists, like this:

buckets = [[]] * 5

You might think it creates 5 independent empty lists. But what actually happens is this:

  • Python creates one list in memory and then references it multiple times.

  • All the elements in buckets point to the same list. So, if you modify one, you modify all!

Here’s an example:

buckets = [[]] * 3
buckets[0].append(1)

print(buckets)  # Output: [[1], [1], [1]]

Surprised? This happens because buckets[0], buckets[1], and buckets[2] are all the same list.


The Fix: Use List Comprehension

To ensure each sublist is an independent object, use a list comprehension:

buckets = [[] for _ in range(5)]

This creates a new, separate list for each position in buckets. Now, modifying one doesn’t affect the others:

buckets[0].append(1)

print(buckets)  # Output: [[1], [], [], [], []]

Why Does This Happen?

The issue boils down to how Python handles mutable objects like lists. When you use * to multiply a list, Python doesn’t create new objects—it just copies the reference to the same object. This is efficient, but it can lead to unintended consequences.


Final Thoughts

When working with lists of lists (or other mutable objects), always ensure they’re independent if that’s what you need. Use tools like list comprehensions to avoid shared reference issues.

Happy coding, and may your lists stay bug-free!