Mutable vs Immutable Objects in Python: Explained with Memory References

Introduction
If you're new to Python, you've probably seen code like this:
numbers1 = [1, 2, 3]
numbers2 = numbers1
numbers1[0] = 100
print(numbers1)
print(numbers2)
Output
[100, 2, 3]
[100, 2, 3]
Most beginners expect only numbers1 to change.
But both variables changed.
Now look at this example.
name1 = "Python"
name2 = name1
name1 += " Rocks"
print(name1)
print(name2)
Output
Python Rocks
Python
This time, only name1 changed.
Why does a list behave differently from a string?
To answer that, we first need to understand mutable and immutable objects.
What are Mutable Objects?
A mutable object is an object whose contents can be modified after it is created.
Common mutable objects in Python:
listdictsetbytearray
Example
numbers = [1, 2, 3]
numbers.append(4)
print(numbers)
Output
[1, 2, 3, 4]
The original list itself was modified.
What are Immutable Objects?
An immutable object cannot be modified after it is created.
Common immutable objects:
intfloatboolstrtuplefrozensetbytes
Example
text = "Python"
text += " Rocks"
print(text)
Output
Python Rocks
At first glance, it looks like the string changed.
But that's not actually what happened.
To understand why, let's see how Python stores variables in memory.
Variables Don't Store Values
Many beginners imagine variables like boxes that contain values.
numbers = [1,2,3]
numbers
┌─────────────┐
│ [1, 2, 3] │
└─────────────┘
In reality, variables are references (or names) that point to objects stored somewhere in memory.
numbers
│
▼
+-------------+
| [1, 2, 3] |
+-------------+
Think of variables as arrows, not boxes.
Example 1: Mutable Object (List)
numbers1 = [1, 2, 3]
numbers2 = numbers1
Memory
numbers1 ─────┐
▼
+-------------+
| [1, 2, 3] |
+-------------+
▲
numbers2 ─────┘
There is only one list object.
Both variables point to it.
Now execute
numbers1[0] = 100
Python modifies the existing list object.
numbers1 ─────┐
▼
+---------------+
| [100, 2, 3] |
+---------------+
▲
numbers2 ─────┘
Since both variables reference the same object, both see the updated values.
Example 2: Immutable Object (String)
name1 = "Python"
name2 = name1
Memory
name1 ───────┐
▼
+----------+
| "Python" |
+----------+
▲
name2 ───────┘
Now execute
name1 += " Rocks"
Strings are immutable.
Python cannot modify the existing string.
Instead, it creates a completely new string object and updates name1 to point to it.
name2
│
▼
+----------+
| "Python" |
+----------+
name1
│
▼
+------------------+
| "Python Rocks" |
+------------------+
The original string still exists because name2 references it.
Mutation vs Rebinding
This is the most important concept in the article.
Mutation
numbers[0] = 100
numbers.append(4)
numbers.pop()
The object changes.
The reference stays the same.
Rebinding
numbers = [4, 5, 6]
text = "Hello"
count = 42
The variable changes what it points to.
The original object is left unchanged.
Key Takeaways
Variables do not store objects; they store references to objects.
Mutable objects can be modified in place.
Immutable objects cannot be modified. Python creates a new object instead.
Assignment (
=) rebinds a variable to another object.Mutating an object affects every variable that references it.



