A small bug introduced me to Immutability in Python

Gauri wankhade
Analytics Vidhya
Published in
2 min readMay 28, 2021

--

Everything in python is an object. Immutability is closely related to memory location of that object.

Before, we talk about immutability let’s go through these examples.

Example 1)

Output:

list1 before mutation:  ['1', '2', '3', '4']
list2 before mutation: ['1', '2', '3', '4']
list1 after mutation: ['1', '8', '3', '4']
list2 after mutation: ['1', '8', '3', '4']

Here, in function, we have updated index 1 of list1. No changes to list2, yet index 1 of list2 updated.

Now, let’s try the same with an integer.

Example 2)

Output:

param1 before mutation:  7
param2 before mutation: 7
param1 after mutation: 9
param2 after mutation: 7

In the above example, we are updating param1 in the function. Unlike the previous example, there is no change to param2.

Why different behaviour from integers?

Integers are believed to be immutable objects. As the name implies immutable objects are ones that once created cannot be updated afterward.

But we do that all the time, don't we? We change the value of integers all the time, just like in Example-2. Then how come it fits into the definition of immutable objects.

To answer that question we have to follow some more examples.

Example 3)

(Here, ‘id’ refers to the memory location of the respective object)

#integers
num1 = num2 = 4
print('num1: ',num1)
print('num2: ',num2)
print('id of num1: ',id(num1))
print('id of num2: ',id(num2))
#mutatingnum1 += 1
num2 += 2
print('num1: ',num1)
print('num2: ',num2)
print('id of num1: ',id(num1))
print('id of num2: ',id(num2))

Output:

num1:  4
num2: 4
id of num1: 4534237584
id of num2: 4534237584
num1: 5
num2: 6
id of num1: 4534237616
id of num2: 4534237648

Observations:

  • Initially, num1 and num2 have the same value and same ids, which means num1 and num2 point to the same memory location.
  • After mutating(incrementing the value of num1 and num2), the respective id of num1 and num2 also changed. This means num1 and num2 are no longer pointing to previous memory locations. Turns out mutation creates new num1 and num2 objects with the brand new memory location.

That is why in Example 2 when we update param1, it did no change to param2. Even though param1 and param2 were referring to the same object initially, after mutating param1 is a whole new object.

Any changes to param1 are no longer related to param2. That’s the reason param2 remained unchanged.

Thank you for reading this article, and I hope you enjoyed it.

--

--