Mutable and Immutable in Python: A Complete Guide (Examples)

In Python, 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

This is a comprehensive guide to understanding the concepts of mutable and immutable in Python. You will find illustrative examples as well as clarifications for common misconceptions about these concepts.

Understanding Mutable and Immutable in Python

Everything in Python is an object. Moreover, every single object falls into the category of being either mutable or immutable.

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

Here are some common Python data types with their related mutability:

TypeMutableImmutable
boolx
intx
floatx
strx
listx
tuplex
setx
frozensetx
dictx

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 an int is an immutable type? You can change an integer, can’t you?

To figure out the answers to these questions, you are going to take a deep dive into the realm of mutability. But before that, you need to learn about an important built-in function, id().

The id() Function in Python

When you create a Python object, the program allocates a chunk of memory to hold that object. There’s a unique address for each Python object that tells the program at which location in memory the object lives.

In Python, each object has a unique ID that is related to the memory location of a Python object. To read the unique ID, you can use the built-in id() function.

For example, let’s read the memory location of an example string variable:

word = "This is an example"

print(id(word))

Output:

4557539968

Mutability in Python

As you already learned, a mutable object can be changed but an immutable object cannot.

One example of an immutable data type in Python is an integer. To realize this, let’s run some simple 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. Let’s make sure this is the case:

a = 1
b = a

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

Output:

True

Thus, the variables a and b are both references to the same integer object behind the scenes. In other words, there’s only one integer object but two variables that point to that object.

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))

Output:

False

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 a new integer object 10.

So even though it looks as if you updated the original integer object, you didn’t. 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))

Output:

True

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))

Result:

True

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:

print(nums)
print(l)

Output:

[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.

“Exceptions” in Immutability

Now that you understand the concepts of mutable and immutable 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.

For example:

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, let’s add a list of numbers as the fourth element of a tuple and change the first number of the list:

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

print(nums)

Output:

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

The first value of the list inside the tuple changed from 1 to 1000 even though a tuple is supposed to be immutable.

This is because a value of a tuple cannot be changed after it is created. But in reality, a value of a tuple is just a reference to an object behind the scenes. These references are immutable, for sure. But the referred objects might still be mutable.

In other words, if a tuple element refers to a list, you can modify the list elements. But you cannot replace the list with another item in the tuple, because the tuple is immutable, and it has to refer to the original values.

Here’s an illustration:

A mutable list inside an immutable tuple

So the value of an immutable object can not change. But the object in memory it points to can (assuming it’s mutable, of course).

Conclusion

In Python, mutability means you can directly modify an object after creation. For example, a list is a mutable object. After creating a list, you can add, modify, or remove elements from it.

Immutability means the inability to change the object after creation. A tuple is a great example of an immutable object. Once you’ve created a tuple, you cannot modify it.

An integer is another great example of immutable in Python. You cannot modify an integer object directly. Instead, you need to create a new one.

Thanks for reading. Happy coding!

Further Reading

Shallow Copy vs Deep Copy in Python

About the Author

Artturi Jalli
I'm an entrepreneur and a blogger from Finland. My goal is to make coding and tech easier for you with comprehensive guides and reviews.