Python's variables aren't buckets that contain things; they're pointers that reference objects.
The way Python's variables work can often confuse folks new to Python, both new programmers and folks moving from other languages like C++ or Java.
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.
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
x this will make
y point to the same memory location as
>>> 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.
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
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
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"
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.
To recap, if we have two variables
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.
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
y is the same as before:
>>> id(x) 2253221617032 >>> id(y) 2253221094088
If we point
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
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:
Hello friendly web visitor! 👋
This page is part of Python Morsels, an online Python skill-building service.
The best way to learn is by doing. In the case of Python that means writing Python code. If you'd like to improve your Python skills every week, try out Python Morsels by entering your email below to create an account.
Python Morsels topics pages are free and the first month's worth of exercises is free as well. You don't need to enter payment details to sign up.
You can find explanations of many other Python topics by signing up below.