Tuples are immutable ordered sequences
similar to lists
Lists aren’t the only kind of ordered sequence in Python. You’ve already learned about one of the others: strings (see Chapter 4, ). Formally, a string is an immutable sequence of characters. The characters in a string are ordered, and a string can be indexed and sliced like a list to create new strings:
| | >>> rock = 'anthracite' |
| | >>> rock[9] |
| | 'e' |
| | >>> rock[0:3] |
| | 'ant' |
| | >>> rock[-5:] |
| | 'acite' |
| | >>> for character in rock[:5]: |
| | ... print(character) |
| | ... |
| | |
| | a |
| | n |
| | t |
| | h |
| | r |
Python also has an immutable sequence type called a tuple. Tuples are written using parentheses instead of brackets; like strings and lists, they can be subscripted, sliced, and looped over:
| | >>> bases = ('A', 'C', 'G', 'T') |
| | >>> for base in bases: |
| | ... print(base) |
| | ... |
| | A |
| | C |
| | G |
| | T |
There’s one small catch: although () represents the empty tuple, a tuple with one element is not written as (x) but as (x,) (with a trailing comma) to avoid ambiguity. If the trailing comma weren’t required, (5 + 3) could mean either 8 (under the rules of arithmetic) or the tuple containing only the value 8:
| | >>> (8) |
| | 8 |
| | >>> type((8)) |
| | <class 'int'> |
| | >>> (8,) |
| | (8,) |
| | >>> type((8,)) |
| | <class 'tuple'> |
| | >>> (5 + 3) |
| | 8 |
| | >>> (5 + 3,) |
| | (8,) |
Unlike lists, once a tuple is created, it cannot be mutated:
| | >>> life = (['Canada', 76.5], ['United States', 75.5], ['Mexico', 72.0]) |
| | >>> life[0] = life[1] |
| | Traceback (most recent call last): |
| | File "<python-input-1>", line 1, in <module> |
| | life[0] = life[1] |
| | ~~~~^^^ |
| | TypeError: 'tuple' object does not support item assignment |
However, the objects inside tuples can still be mutated:
| | >>> life = (['Canada', 76.5], ['United States', 75.5], ['Mexico', 72.0]) |
| | >>> life[0][1] = 80.0 |
| | >>> life |
| | (['Canada', 80.0], ['United States', 75.5], ['Mexico', 72.0]) |
Here is an example that explores what is mutable and what isn’t. Let’s build the same tuple as in the previous example, but let’s do it in steps. First, let’s create three lists:
| | >>> canada = ['Canada', 76.5] |
| | >>> usa = ['United States', 75.5] |
| | >>> mexico = ['Mexico', 72.0] |
That builds this memory model:

Let’s create a tuple using those variables:
| | >>> life = (canada, usa, mexico) |

Notice that none of the four variables know about the others, and that the tuple object contains three references, one for each of the country lists.
Now, let’s change what variable mexico refers to:
| | >>> mexico = ['Mexico', 72.5] |
| | >>> life |
| | (['Canada', 76.5], ['United States', 75.5], ['Mexico', 72.0]) |
Notice that the tuple that the variable life refers to hasn’t changed. Here’s the new picture.

life[0] will always refer to the same list object—we can’t change the memory address stored in life[0]—but we can mutate that list object. And because variable canada also refers to that list, it sees the mutation:
| | >>> life[0][1] = 80.0 |
| | >>> canada |
| | ['Canada', 80.0] |

We hope it is clear how essential it is to thoroughly understand variables and references, as well as how collections contain references to objects, not variables.
You can assign to multiple variables in the same assignment statement:
| | >>> (x, y) = (10, 20) |
| | >>> x |
| | 10 |
| | >>> y |
| | 20 |
As with a normal assignment statement (see ), Python first evaluates all expressions on the right side of the = symbol, and then it assigns those values to the variables on the left side.
Python uses the comma as a tuple constructor, allowing you to omit the parentheses:
| | >>> 10, 20 |
| | (10, 20) |
| | >>> x, y = 10, 20 |
| | >>> x |
| | 10 |
| | >>> y |
| | 20 |
Multiple assignment also works with lists and sets. Python will happily unpack information from any collection:
| | >>> [[w, x], [[y], z]] = [{10, 20}, [(30,), 40]] |
| | >>> w |
| | 10 |
| | >>> x |
| | 20 |
| | >>> y |
| | 30 |
| | >>> z |
| | 40 |
Any depth of nesting will work as long as the structure on the right can be translated into the structure on the left.
One of the most common uses of multiple assignment is to swap the values of two variables:
| | >>> s1 = 'first' |
| | >>> s2 = 'second' |
| | >>> s1, s2 = s2, s1 |
| | >>> s1 |
| | 'second' |
| | >>> s2 |
| | 'first' |
The assignment works because the expressions on the RHS are evaluated before being assigned to the variables on the LHS. We will revisit multiple assignments in .