Python Objects 101 — Mutable vs Immutable

Yago Martinez-Falero Hein
The Startup
Published in
4 min readJan 13, 2021

--

Python ‘variables’, at first, seem to have superpowers! You can assign an int, a float, a list, a dict… But that what you might want to call a ‘variable’ isn’t really one and that’s the magic of python!

In python, everything is an object, and the so-called ‘variables’ are more like a label with a reference to an object. And those objects have particular characteristics that any newcomer must learn about.

Introduction

What does immutable and mutable mean? Well:

Simply placed, after it is made, a mutable object can be altered, while an immutable object can’t.

When you initiate an object, Python gives it a unique ID. Once its type is set, it cannot be changed, however, some objects can have their state modified. Here’s the full list of mutable and immutable objects:

Id and type

We talked about ID and type previously but let dive deeper into how this actually works.

Python has two built-in functions that allow you to retrieve the unique id of an object and its type:

id() : returns the ID in the form of an int which corresponds to its address in memory.

type() : return the type of the object.

Let’s see an example:

>>> a = 1
>>> b = "foo"
>>> id(a)
4335832752
>>> id(b)
4339084568
>>> type(a)
<class 'int'>
>>> type(b)
<class 'str'>

A little notice before we carry on:

Variables are not objects. Variables point to objects in memory by storing their address i.e. their id() . Rather than variable we call them identifiers.

As we can see, id() and type() allows us to see if they are the same object or if they have the same type. But we can also figure that out this way:

>>> a = 1
>>> b = "foo"
>>> a is b '''comparing the types'''
False

Mutable and Immutable Objects

Immutable Objects:

Let’s go over the following example to understand the mutability of object types:

x = 5
y = x

Here we created an object of type int. Let’s look at their IDs:

>>> id(x)
4538056496
>>> id(y)
4538056496
>>> id(5)
4538056496

So here we see: id(x) == id(y) == id(5)

If we do the following operation: x = x * 2 then the IDs will be the following:

>>> id(x)
4538056656
>>> id(y)
4538056496
>>> id(5)
4538056496

Here id(x) != id(y) and id(5)

Therefore, immutable objects CANNOT be modified after their creation.

Mutable Objects:

l1 = list([1, 2, 3])
l2 = l1

In this example, we created two objects of type list . Let’s look at their IDs:

>>> id(l1)
4541599816
>>> id(l2)
4541599816

Let’s add an item to the list l1.append(4) and check their IDs once more:

>>> id(l1)
4541599816
>>> id(l2)
4541599816

Here: id(l1) == id(l2)

Therefore, mutable objects CAN be modified after their creation.

Now we know the main difference between mutable and immutable objects.

How Differently Does Python Treat Mutable And Immutable Objects?

  • Immutable objects are quicker to access
  • Mutable objects are slower to access.
  • Immutables are used when you need to ensure that the object you made will always stay the same.
  • Mutable objects are great to use when you need to change the size of the object, for example, list, dict etc..
  • Immutable objects are fundamentally expensive to “change”, because doing so involves creating a copy.
  • Changing mutable objects is cheap.

Exceptions

The Python tuple-like containers are immutable. That means you can’t adjust the value of a tuple after it’s made.

But a tuple’s ‘value’ is simply a list of names that have unchangeable object bindings.

The key thing to note is that the bindings are unchangeable, not the objects they are bound to.

For example, t = ('foo', [1, 2, 3]) combines an immutable string with a mutable list. So… The tuple is immutable and its string content too, but the list is mutable.

The “value” of an immutable object can’t change, but it’s constituent objects can.

Objects Passed To Functions

Here we want to know more about how arguments are passed to functions and what does that imply for mutable and immutable objects.

Here is the book definition:

Python uses a mechanism, which is known as “Call-by-Object”, sometimes also called “Call by Object Reference” or “Call by Sharing”.

Immutable:

If you pass to a function immutable arguments such as integers, strings, or tuples, the passing works like call-by-value.

The object referenced is passed on to the parameters of the function. Inside, they can’t be modified so they can’t be changed at all, i.e., they’re immutable.

>>> def ref_demo(x):
... print "x=",x," id=",id(x)
... x=42
... print "x=",x," id=",id(x)
...
>>> x = 9
>>> id(x)
41902552
>>> ref_demo(x)
x= 9 id= 41902552
x= 42 id= 41903752
>>> id(x)
41902552

Mutable:

They are often transferred via object relation, but in the function, they can be modified in place.

If we pass a list to a function, we have to remember two cases:

  • It is possible to modify the list elements in place, i.e. the list can be changed even within the scope of the caller.
  • If the name is assigned to a new list, the existing list will not be changed, i.e. the list beyond the control of the caller will remain unchanged.
>>> def ref_demo(l):
... print l
... l += [47,11]
... print l
...
>>> list_1 = [1, 2, 3]
>>> ref_demo(list_1)
[1, 2, 3]
[1, 2, 3, 47, 11]
>>> print list_1
[1, 2, 3, 47, 11]

--

--

Yago Martinez-Falero Hein
The Startup

👨🏼‍💻 Entrepreneur and software engeneer // Former employee at TheFamily.co // 👨🏼‍🎓 Holberton School & Reverse Origins