[Go to site: main page, start]

Mutable tuples PREMIUM

Tuples are immutable in Python, but tuples can contain mutable objects. So (strangely) if a tuple contains a mutable object, it's possible for the value of that tuple to change.

Trey Hunner Trey Hunner 3 min read 03:23 video Python 3.10—3.14
Watch this as a 03:23 screencast
Same content, narrated. Your preference is remembered for next time.
Watch it

Tuples in Python are immutable, meaning you cannot mutate them; you cannot change them. Except you can change the value of a tuple... sort of.

Tuples can contain mutable objects

We have a dictionary here, called data:

>>> data = {"name": "Trey", "color": "purple"}

And we have a two-item tuple (result) that contains a boolean (True), and a dictionary (the dictionary that the data variable points to).

>>> result = (True, data)

This is already a little bit odd because we have a an immutable data structure (a tuple) which contains a mutable data structure (a dictionary).

>>> result
(True, {'name': 'Trey', 'color': 'purple'})

Let's make another tuple which contains the same boolean and a copy of the same dictionary:

>>> result2 = (True, data.copy())

Right now, result is equal to result2:

>>> result == result2
True

These two tuples represent the same data.

Mutating a tuple item is all we need

We can index our result tuple to get access to the dictionary within it:

>>> result[1]
{'name': 'Trey', 'color': 'purple'}

And once we have access to this dictionary, there's nothing stopping us from changing one of the items within it:

>>> result[1]["color"] = "pink"

If you can get your hands on a mutable object, you can mutate that object.

But that means our tuple has changed:

>>> result
(True, {'name': 'Trey', 'color': 'pink'})

Or at least it seems like our tuple has changed.

We didn't actually mutate our tuple: we mutated an object that happens to be pointed to by our tuple. Remember that just like variables, data structures in Python do not contain objects, data structures point to objects.

So this tuple points to a boolean (True) and it points to a dictionary:

>>> result
(True, {'name': 'Trey', 'color': 'pink'})

And in fact, our data variable points to the same dictionary:

>>> data
{'name': 'Trey', 'color': 'pink'}

So data changed as well... or rather the object that data is pointing to changed as well.

Our other tuple, result2, didn't change:

>>> result2
(True, {'name': 'Trey', 'color': 'purple'})

It didn't change because we had copied our original data dictionary when we made that tuple:

>>> result2 = (True, data.copy())

We are referring to a different object in tuple result2 so the color didn't change when we changed the dictionary in result.

But since result and result2 contain dictionaries with different values, these two tuples aren't equal anymore:

>>> result == result2
False

When you ask whether two tuples are equal (using the == operator) those tuples will check the objects with them for equality (more on tuple comparisons).

So while you can't mutate a tuple, if your tuple contains a mutable object (or rather points to a mutable object since data structures don't actually contain objects), you can always mutate that mutable object it contains. If you mutate something that happens to be contained inside a tuple (pointed to by a tuple), then it will seem like you've just changed the tuple itself. The equality value of that tuple will have changed.

Summary

Tuples are immutable in Python, meaning you can't change them but tuples can contain mutable objects and you can change mutable objects, regardless of which data structures or variables might be pointing to them.

This doesn't usually concern us that much in Python though because, we don't often use tuples for their immutability, usually we use tuples for the ease with which we can squish together a couple different objects and stick them into a tuple and then unpack that tuple later.

Next up
When is equality the same as identity?
04:55 watch

When comparing whether two objects are equal in Python, you should use the == operator to check for equality. Don't use the is operator unless you actually care about identity, which is pretty rare. But why not use is? What's the downside?

Watch
This is a free preview of a premium screencast. You have 2 previews remaining.