Skip to main content

Command Palette

Search for a command to run...

Mutability & Identity in Python

Updated
7 min read

Before learning advanced Python, you must understand one question:

When you change a value, are you changing the object itself, or creating a new object?

Most beginner bugs around lists, functions, dictionaries, classes, and memory come from not understanding this.

This article explains:

  • Mutable vs Immutable Objects

  • Object Identity

  • id()

  • Equality vs Identity

  • == vs is

  • Shared References

  • Aliasing

  • Side Effects of Mutation

From first principles.

1. The Fundamental Question

Imagine writing a name on a piece of paper.

You have two choices:

Option A

Erase the old name and write a new one on the same paper.

The paper stays the same.

Only the content changes.

Option B

Throw away the old paper.

Create an entirely new paper with the new name.

The content changes because the object itself changed.


Python objects behave the same way.

Some objects allow modification.

Some do not.

This leads us to the first concept.

2. Mutable vs Immutable Objects

First Principle

An object is either:

Mutable

Can change after creation.

Immutable

Cannot change after creation.


Analogy

Think about:

Mutable → Whiteboard

You can erase and rewrite.

Same board.

Different content.

Immutable → Printed Book

Cannot modify the printed text.

If you want different text, print a new book.


Common Immutable Types

int
float
bool
str
tuple
frozenset

Example:

x = 10

x = x + 1

Looks like modification.

But actually:

  1. Create object 10

  2. Create object 11

  3. Make x point to 11

The object 10 never changed.


Common Mutable Types

list
dict
set
most custom objects

Example:

numbers = [1, 2, 3]

numbers.append(4)

The same list object changed.

No new list created.

3. Object Identity

First Principle

Every object in memory has an identity.

Identity answers:

"Which exact object is this?"

Not:

"What value does it contain?"


Analogy

Imagine two identical twins.

They may look identical.

But they are different people.

Identity is about who.

Not what.


Example:

a = [1, 2, 3]
b = [1, 2, 3]

Same values.

Different objects.

Memory:

a → List A
b → List B

Python treats them as separate objects.

4. id() — Seeing Identity

Python provides:

id()

to inspect object identity.


Example:

a = [1, 2, 3]

print(id(a))

Output:

140512839204416

(The number differs on every machine.)


Think of it as:

House Number

for an object.

Two different houses may look identical.

Their addresses differ.


Example:

a = [1, 2]
b = [1, 2]

print(id(a))
print(id(b))

Different identities.

Different objects.

5. Equality vs Identity

This is where many beginners get confused.


Equality

Asks:

"Do these objects contain the same value?"


Identity

Asks:

"Are these literally the same object?"


Analogy:

Two ₹500 notes.

Equal value?

Yes.

Same physical note?

No.


Example:

a = [1, 2, 3]
b = [1, 2, 3]

Values:

a == b

Result:

True

Because contents match.


Identity:

a is b

Result:

False

Because they are different objects.

6. == vs is

These operators answer different questions.


==

Checks value equality.

a == b

asks:

Do they contain the same data?

is

Checks identity.

a is b

asks:

Are they literally the same object?

Example:

a = [1, 2]
b = [1, 2]

print(a == b)
print(a is b)

Output:

True
False

Visualization:

a ──► [1,2]

b ──► [1,2]

Two objects.

Same values.

Different identities.

7. Shared References

Now things get interesting.


Example:

a = [1, 2, 3]

b = a

Many beginners think:

Copy happened

No.


Actual memory:

a ─┐
   ▼
 [1,2,3]
   ▲
b ─┘

Both variables point to the same object.


Check:

a is b

Output:

True

Same object.

Same identity.

Same memory.

8. Aliasing

When multiple names refer to the same object:

a = [1, 2, 3]
b = a

This is called:

Aliasing


Analogy

You:

Aman

may also be called:

Friend
Student
Developer

Different names.

Same person.


Similarly:

a
b

are different names.

Same object.

9. Mutation Through Aliases

Now observe:

a = [1, 2, 3]

b = a

b.append(4)

print(a)

Output:

[1, 2, 3, 4]

Many beginners expect:

[1, 2, 3]

But that's wrong.


Why?

Because:

a and b

point to the same list.

Changing through one name changes the object.

The other name sees the same change.


Memory:

Before:

a ─┐
   ▼
 [1,2,3]
   ▲
b ─┘

After:

a ─┐
   ▼
 [1,2,3,4]
   ▲
b ─┘

10. Side Effects of Mutation

First Principle

A side effect happens when modifying an object affects code outside the current location.


Example:

def add_item(items):
    items.append("Python")

courses = ["C"]

add_item(courses)

print(courses)

Output:

['C', 'Python']

Why?

Function parameter:

items

and variable:

courses

point to the same list.


Memory:

courses ─┐
         ▼
      ['C']
         ▲
items ───┘

Function mutates the list.

Caller sees the change.


This is one of the most common beginner bugs.

11. Avoiding Mutation Side Effects

Create a copy.

courses = ["C"]

new_courses = courses.copy()

new_courses.append("Python")

Now:

courses

remains unchanged.


Memory:

courses     ─► ['C']

new_courses ─► ['C','Python']

Two separate objects.

12. Immutable Objects Behave Differently

Example:

x = 10
y = x

y += 5

Many people expect:

x = 15

Wrong.


Why?

Integers are immutable.

Python creates a new object.


Before:

x ─┐
   ▼
  10
   ▲
y ─┘

After:

x ─► 10

y ─► 15

Original object unchanged.

13. Mental Model

Whenever you write Python, ask:

Question 1

Is this object mutable?

list, dict, set → Yes

int, str, tuple → No

Question 2

Am I creating a new object?

or

Am I modifying an existing object?


Question 3

Are multiple variables pointing to the same object?

b = a

If yes:

Mutation through one name affects all names.

Question 4

Do I care about value or identity?

Value:

==

Identity:

is

Final Takeaway

Everything in this chapter comes from one idea:

Variables do not store objects. Variables store references to objects.

Once you understand that:

  • Mutability becomes obvious

  • Identity becomes obvious

  • id() makes sense

  • == vs is becomes clear

  • Aliasing becomes predictable

  • Mutation side effects stop being mysterious

Think of variables as labels.

Think of objects as actual things.

Multiple labels can point to the same thing.

If that thing is mutable, changing it through one label changes it for everyone.