Mutable and Immutable objects in Python

Renato Leon
7 min readMay 31, 2021

Python, as you may know can get a little bit crazy sometimes for the easiness it gives to programmers to write code, in my path of learning this language I’ve encountered some cases when the expected output was different from the output that the code produces. To understand this better, let’s see what could happen when dealing with mutable and immutable objects when coding in python.

Mutable objects as the name suggests are object which values can change during the programs execution while immutable object values’ cannot, the understanding of these two concepts could help avoid unexpected behaviour in our program.

As the python datamodel reference says:

The value of some objects can change. Objects whose value can change are said to be mutable; objects whose value is unchangeable once they are created are called immutable. (The value of an immutable container object that contains a reference to a mutable object can change when the latter’s value is changed; however the container is still considered immutable, because the collection of objects it contains cannot be changed. So, immutability is not strictly the same as having an unchangeable value, it is more subtle.) An object’s mutability is determined by its type; for instance, numbers, strings and tuples are immutable, while dictionaries and lists are mutable.

Id and Type

In python ‘id’ is a function that will give back a unique identifier as a number for each object, depeding on the python implmentation this id can vary, for example in CPtyhon this function will give back the memory address at wich the object is stored. To quote the datamodel reference again:

Every object has an identity, a type and a value. An object’s identity never changes once it has been created; you may think of it as the object’s address in memory. The ‘is’ operator compares the identity of two objects; the id() function returns an integer representing its identity.

CPython implementation detail: For CPython, id(x) is the memory address where x is stored.

Let’s take a look at some examples using ‘id’ function:

As we can see each object has its own id, other function worth mentioning is ‘type’ which will return the object’s type:

Mutable objects

We can think of mutable as something that can be changed, in OOP context, mutable objects’ value can be manipulated, thus changing the objects’ data but mantaining its identity, let’s take for example a list object which is mutable:

When we define the list, an id its given to it, an will be mantained as long as the list object lives in our program, we can see that the list value at the start contains the numbers from 1 to 3, then we append a new element ‘4’ thus changing or mutating the list, and even after this change, th list keeps it’s identity, thus we can say that the variable ‘ls’ is still refering to same object, in this case no new object was created.

Immutable objects

Immutable objects in the other hand are objects that cannot be changed and even if we try or thing about changing them what will happen is that a new object will be created instead, let’s see what I mean through an example:

In this example we use a string object, which is immutable, to demonstrate what we said earlier, even though we can thing that we’re changing the object’s value, we can see that in this case tha’s not what happend, what really happened is that when ‘s’ was created an ‘id’ was assigned to it, next when we tried to modify it’s value, a new object got created and the ‘id’ of that object got assigned to ‘s’ variable, thus, the original object was not mutated, instead was replaced by another object wich contained the contatenation of the previous value with the new one, and that is why at the end the ‘id’ we got was different from the ‘id’ at the begining.

How python treat mutable and Immutable objects

As you may know, in python everything is an object, even a simple number as ‘1’ or ‘2’ is considered to be an object. Mutable and immutable objects can be a little tricky when dealing with them, let’s see what I mean, first let’s make a list of what objects are consider mutable and which ones are considered immutable:

  • Mutable Objects: list, dict, set
  • Immutable objects: int, float, complex, string, tuple, frozen set, byte

This first example will consist of a list wich will be referenced by two variables which wil be treated as aliased due they will refer to the same object, and because a list is mutable, it’s value can be modified from either of the aliases:

As we can see the list was mutated because the variable aliased to it holded a reference to the exact same object and thus it was able to change it’s value, maybe the following picture will help clearing out what happened here:

As the image shows, both variables reference the same object, any change to this object can be seen from any variable that holds a reference to it.

In python we can make use of the ‘is’ operator to check if two variables refer to same object or not:

If we want to see if a value stored in one object is the same as other object we can use the '==’ operator, let’s make a new example:

The operation gives back ‘True’ because the contents of both lists are the same, now if we use the ‘is’ operator we’ll expect to give back False because each list is refering to a diferent object:

And get ‘False’ as expected.

For immutable objects this last behaviour is quite different, let’s take strings as example:

In this case the ‘is’ operator gives back True due to the way python manages immutable types for memory efficiency thus not creating new objects and instead giving back the addresses at wich they are stored in memory.

We can see a similar behavior when using int types:

For int type, this behavior can be explained by something known asNSMALLPOSINTSandNSMALLNEGINTSwhich consists of an array of 262 integers defined in the python implementation to improve memory efficiency due to this integers are the most commonly used, and thus, creating a variable with value in a range from -5 to 256 inclusive will give back a reference to the number inside this array.

How arguments are passed to functions

In python as we know everything is an object, thus when we pass a variable as function argument, theoretically we’re passing a reference to that variable, knowing this, we can think that we could change any object’s value inside a function, but is not that simple, python handles this references differently depending if the object passed to a function is mutable or not, let’s see an example:

example code, passing a mutable object as function argument
output

In this case the list object was mutated, it’s value was changed from inside the function due to a ‘list’ is a mutable object.

Now an example using an immutable object:

example code, passing an immutable object as function argument
output

As we can see the string didn’t change after the function was called, this is because strings, as we mentioned earier, are immutable objects and thus it ‘s value cannot be modified, what happend inside the funcion was that a new object was created and assigned to ‘s_ref’ variable, but this object will only exist until the function ends it’s execution thus not afecting the original object referenced by the ‘s’ variable.

That’s it for this post!!!, as always, hope this helped you in some way, take care and see you on the next one.

--

--