Skip to main content

Command Palette

Search for a command to run...

Mutable vs Immutable Objects in Python: Explained with Memory References

Updated
•3 min read•View as Markdown
Mutable vs Immutable Objects in Python: Explained with Memory References
M
Just a tech guy

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:

  • list

  • dict

  • set

  • bytearray

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:

  • int

  • float

  • bool

  • str

  • tuple

  • frozenset

  • bytes

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.