The 2 Types of "Change" in Python

Watch First:


Transcript

The word "change" is ambiguous in Python: we have two distinct types of "change" in Python.

We can "change" a variable by changing which object that variable is pointing to. We do that through an assignment statement.

We can also "change" an actual object through a mutation.

Let's take a look at both types of change.

Assignments

Let’s say we have a variable x pointing to the value 4.

>>> x = 4

We can use the built-in id function to get the memory location of the object this variable x is pointing to (this unique identifier will never change for the lifetime of an object):

>>> id(x)
140727864255408

If we point x to a new object, say a list, it's id will change:

>>> x = [1, 2, 3]
>>> id(x)
2253221094088

If we assign y to x this will make y point to the same memory location as x:

>>> y = x
>>> id (y)
2253221094088

This is the first type of change: assignment. We can change which object a variable is pointing to by doing an assignment.

Mutation

The second type of "change" is mutation. Assignment changes variables, but mutation changes objects.

Most Python objects can be changed after they've been created. Lists, sets, and dictionaries can all be changed, whereas tuples, numbers, and strings cannot. Objects that can be changed are called mutable and the act of changing one of these objects is a mutation.

Assignment pretty much always involves an = sign, whereas mutation can take a lot of forms: one form is a method call. For example calling the append method on a list.

Let's take our list from before which both x and y point to:

>>> x
[1, 2, 3]
>>> y
[1, 2, 3]
>>> id(x)
2253221094088
>>> id (y)
2253221094088

And we'll call the append method on the variable x to add a new item to our list:

>>> x.append(4)
>>> x
[1, 2, 3, 4]

Remember that both y and x point to the same object, so if we look at y it'll seem to have changed as well:

>>> y
[1, 2, 3, 4]

Note that we didn't actually "change" x or y because the id of these two variable is the same as before:

>>> id(x)
2253221094088
>>> id (y)
2253221094088

Instead we changed the object that these two variables are pointing to.

Summary

To recap, if we have two variables x and y and they both point to the same object in memory:

>>> x
[1, 2, 3, 4]
>>> y
[1, 2, 3, 4]
>>> id(x)
2253221094088
>>> id (y)
2253221094088

If we then reassigned x to a new list:

>>> x = [4, 5, 6]
>>> x
[4, 5, 6]

I've done an assignment which means I've changed which object the variable x is pointing to.

The variable x has changed here but y has not:

>>> y
[1, 2, 3, 4]

Because we didn't point y anywhere new: we only pointed x to a new object, so its id has changed but the id of y is the same as before:

>>> id(x)
2253221617032
>>> id(y)
2253221094088

If we point x and y back to same object and then call a method on this object to ask it to mutate itself:

>>> x = y
>>> x
[1, 2, 3, 4]
>>> x.pop()
4

Both x and y will reflect this change:

>>> x
[1, 2, 3]
>>> y
[1, 2, 3]

Because these two variables point to the same object:

>>> id(x)
2253221094088
>>> id(y)
2253221094088

So the two types of change in Python are:

  1. Assignment, which changes which object a variable points to
  2. mutation, which changes an object itself (that will appear to change every variable that points to that object)