Python Mutability Explained

Python mutability refers to being able to change an object. Simply put, a mutable object can be changed, but an immutable object cannot.

For example, a tuple is an immutable data type. You cannot change its elements after creating it:

nums = (1, 2, 3)
nums[0] = 100 # ERROR!

In contrast, a list is a mutable collection. You can change its contents afterward:

nums = [1, 2, 3]
nums[0] = 100 # Works

How to Understand Python Mutability

Everything in Python is an object. Each object falls into the category of being mutable or immutable.

When you create a Python object it gets a unique object id under the hood. Depending on whether the type is mutable or immutable, its state can be changed.

Here are some common data types and the related mutability:


But what does immutability really mean behind the scenes in Python? How could you find out whether something is mutable or not? And how come is an int is an immutable type? You can change an integer, can’t you?

To figure out the answers to these questions, please read along.

Before taking a deeper look at Python mutability, you need to learn what the built-in id() function does.

The id() Function in Python

Each and every Python object has a unique ID that is related to the memory location of a Python object.

The id() function returns this object ID.

For instance:

word = "This is an example"




This shows you that the id is a random integer value that represents the memory location of the string.

Mutability in Python

A mutable object can be changed but an immutable object cannot.

As you know, an integer is an immutable type in Python.

Let me demonstrate how you can realize this by running some experiments. First, let’s create two variables a and b. The variable a is an integer, and the variable b refers to a:

a = 1
b = a

Now both a and b point to the same memory address. In other words, the id() function should return the same ID for both integers:

a = 1
b = a

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



And this is indeed the case.

But now, let’s change the value of a:

a = 10

Now, let’s compare the IDs of a and b again:

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



The IDs don’t match anymore. This is because now a points to a different integer object. In other words, the integer object 1 itself never changed. But the variable a that pointed to it now points to another integer object called 10.

So even though it looks as if you updated the original integer object, you did not. This is due to the fact that an integer is an immutable type in Python, and you cannot change an immutable object after creation.

Now, let’s repeat a similar experiment with a mutable object.

For example, let’s create a list:

nums = [1, 2, 3]
l = nums

Now, let’s compare the IDs of the lists:

print(id(nums) == id(l))



Now, let’s modify the list object by removing its first element:

del nums[0]

Let’s then check if the IDs of the two lists still match:

print(id(nums) == id(l))



And they do! This means nums and l still point to the same list object in memory.

To make the point clear, let’s print the contents of nums and l:



[2, 3]
[2, 3]

This shows that by removing the first element you were clearly able to directly modify the list object. Thus, the list object must be mutable. And this is indeed the case in Python.

To Recap

  • In the integer’s case, the integer object itself did not change because it is immutable. Instead, the variable started pointing to a different integer object in memory.
  • But a mutable list object can change. So its memory address does not change when you modify it. This is because even though you change how it looks, it is still the very same list object under the hood.

“Exceptions” in Immutability

Now that you understand mutability in Python, let’s have a look at an example that can cause confusion.

In Python, tuples are immutable data types. This means once you create a tuple, you cannot replace, add, or remove its elements:

nums = (1, 2, 3)
nums[0] = 100 # ERROR!

But here is where it gets interesting. If you store a list (mutable type) into a tuple, you can still change the contents of that list.

For instance:

nums = (1, 2, 3, [10, 20, 30])

#Change the first value of the list in the tuple from 1 to 1000:
nums[3][0] = 1000



(1, 2, 3, [1000, 20, 30])

Here you can see how the first value of the list inside the tuple changed from 1 to 1000.

But how is this possible? A tuple is immutable, so it should not change, right?

The value of a tuple cannot be changed after it is created. But in reality, a value of a tuple is just a name that is bound to an object behind the scenes. These bindings are immutable, but not the objects they are bound to.

In other words, if a tuple element points to a mutable list, you can modify the elements of the list. But you cannot replace the list with another item in the tuple. This would break an unbreakable binding.

So the value of an immutable object can not change. But the object it points to can change (if it is mutable).


Python mutability means an object’s ability to change. An immutable object cannot change, but a mutable object can.

For example, a list is mutable, but a tuple is not. In other words, you can freely change the elements of a list, but not the ones of a tuple.

Further Reading

Shallow Copy vs Deep Copy in Python

Leave a Comment

Your email address will not be published.