DEV Community

Anton Shcherbatov
Anton Shcherbatov

Posted on

Mutable and Immutable Objects in Python

We assume you already know how to write simple Python programs and understand basic syntax (if, for, functions, lists). Here, we're not discussing how to use the language, but why it works the way it does.

In the previous article, we discovered something interesting.

Lists can be modified:

numbers = [1, 2]

numbers.append(3)

print(numbers)
Enter fullscreen mode Exit fullscreen mode

The output is:

[1, 2, 3]
Enter fullscreen mode Exit fullscreen mode

Numbers, however, behave differently.

When we write:

x = 10
x = 20
Enter fullscreen mode Exit fullscreen mode

the object 10 doesn't somehow become 20. Instead, the name x simply becomes bound to a different object.

At first glance, these seem like two completely different behaviors.

In reality, they come from one of Python's most fundamental ideas.

Python divides its objects into two broad categories:

  • mutable objects
  • immutable objects

Let's start with mutable objects.

A mutable object is one whose internal state can be changed after it's created.

Lists are the classic example.

Suppose we create a list:

numbers = [1, 2]
Enter fullscreen mode Exit fullscreen mode

We can then add elements:

numbers.append(3)
Enter fullscreen mode Exit fullscreen mode

remove them:

numbers.remove(2)
Enter fullscreen mode Exit fullscreen mode

or replace existing values:

numbers[0] = 100
Enter fullscreen mode Exit fullscreen mode

In every case, Python is working with the same object.

The object isn't replaced or recreated.

Only its contents change.

That's why multiple names referring to the same list all observe the same changes.


Now let's look at immutable objects.

Once an immutable object has been created, its state can never change.

Take a number:

x = 10
Enter fullscreen mode Exit fullscreen mode

Now assign a different value:

x = 20
Enter fullscreen mode Exit fullscreen mode

It may look as though the object changed.

But that's not what happened.

The object 10 remains exactly as it was.

The name x simply stops referring to it and becomes bound to another object instead.

The same idea applies to strings.

Suppose we write:

name = "Python"
Enter fullscreen mode Exit fullscreen mode

Now we "add" some text:

name = name + " 3"
Enter fullscreen mode Exit fullscreen mode

It looks like the string has been modified.

In reality, Python creates an entirely new string:

"Python 3"
Enter fullscreen mode Exit fullscreen mode

and rebinds the name name to it.

The original string "Python" never changes.


At this point, it's worth emphasizing one important idea.

When we describe an object as mutable or immutable, we're talking about the object itself.

Not the variable.

Not the name.

Not the assignment statement.

The property belongs to the object that exists in memory.

This distinction may seem subtle now, but it'll help us avoid many common mistakes later on.


So which built-in objects are immutable?

Some of the most common examples are:

10
3.14
True
"hello"
(1, 2, 3)
Enter fullscreen mode Exit fullscreen mode

These include:

  • integers;
  • floating-point numbers;
  • booleans;
  • strings;
  • tuples.

Once created, none of these objects can be modified.

Common mutable objects include:

[1, 2, 3]
{"name": "Anton"}
{"python", "java"}
Enter fullscreen mode Exit fullscreen mode

These are:

  • lists;
  • dictionaries;
  • sets.

Their contents can be changed after they're created.


At this point, you might be wondering:

If mutable objects are so flexible, why isn't everything mutable?

The answer is that immutable objects offer several important advantages.

Since they can never change, Python can safely share and reuse them in many situations, compare them efficiently, and make certain internal optimizations.

They're also easier to reason about.

If an object is immutable, you never have to worry that some other part of your program has modified it behind your back.

That's why Python includes both mutable and immutable objects.

Each serves a different purpose.


We can now summarize Python's object model a little more precisely.

When you write:

x = something
Enter fullscreen mode Exit fullscreen mode

Python doesn't store a value inside a variable.

It binds a name to an object.

What happens next depends on the object itself.

If the object is mutable, its state can be modified in place.

If it's immutable, any apparent "change" results in a different object, with the name simply being rebound to it.


Now we're finally ready for another interesting question.

Suppose we have two lists containing exactly the same values:

a = [1, 2, 3]
b = [1, 2, 3]
Enter fullscreen mode Exit fullscreen mode

Are they actually the same object?

Or are they merely equal?

And why does Python sometimes use ==, while other times is is the right choice?

That's exactly what we'll explore in the next article. 🚀

Top comments (0)