Mutable and immutable objects

Table of Contents

Is this what you expect?

The result of the code below is probably what you expect.

a = 3
b = a
print(a, b)
b = b + 9
print(a, b)
3 3
3 12

Here is similar code that uses lists instead, but the result might surprise you.

a = [3, 4, 5]
b = a
print(a, b)
b.append(6)
print(a, b)
[3, 4, 5] [3, 4, 5]
[3, 4, 5, 6] [3, 4, 5, 6]

Notice that we changed b by appending 6, yet the value of a has also changed. In order to understand these examples, we need to cover the concept of "variables" in Python and the concept of mutability.

Variables in Python

The example above shows that a has to be linked in some way to b beyond just initially sharing values. In other words, assigning a to b doesn't just simply copy over the values of a. So what is happening?

Variables can be thought of as names that are attached to a value. A name itself is not the value. For example, a above is not a list. At that point in time, it refers to a particular list.

Sorry, your browser does not support SVG.

After we assign b = a, now b is another name that attached to the same list.

Sorry, your browser does not support SVG.

The above diagrams should make it clear what is happening in the example with lists. The value of a changes when b is modified because they are referring to the same thing.

Mutability

The logic above explains why b changes along with a, but why didn't the example with integers behave the same way? This has to do with an important difference between integers and lists: lists are mutable while integers are not. Being mutable means that the value can be changed in-place. Let's walk through the integer scenario in diagrams.

After both a is assigned to 3 and then b is assigned to a, it looks like this:

Sorry, your browser does not support SVG.

Once we modify b by adding 9, b now refers to a new value, while a is still bound to the original value.

Sorry, your browser does not support SVG.

Notice that 3 still exists, unmodified. Now, a second value exists, and the name b is now bound to it, while a still refers to 3. This is very different than the list that we changed in-place. This is why we have write b = b + 9 instead of just b + 9. In order to change the value of b, we need to reassign the name a because we can't change the underlying value.

Mutability of some common types

Type Mutable
int no
string no
tuple no
list yes
dict yes

More information

Both of these articles provide great explanations (full of pretty diagrams) of assignments and mutability:

Released under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

Created with Emacs 24.4.1 (Org mode 8.3beta)

Validate