Tuples and unpacking
Group values in immutable tuples, pull them apart by unpacking, and collect leftovers with star syntax.
What you will learn
- Create tuples, including the one-item case
- Explain what immutability does and does not protect
- Unpack tuples and lists into names, including with a starred name
- Spot the several-values-at-once idiom behind divmod, swapping and enumerate
On this page
A list says “a changeable pile of things”. Sometimes you want the opposite: a small, fixed bundle, such as an (x, y) point or a (name, year) pair. That is a tuple. Tuples also power one of Python’s nicest habits, unpacking, which lets you pull a bundle apart into named pieces in a single line.
Tuples
point = (3, 4)print(point[0], point[1], len(point))3 4 2A tuple is an ordered sequence like a list, with indexing, slicing, len and in. The difference is that it is immutable: once built, you cannot assign to an index, append or remove.
point = (3, 4)point[0] = 10TypeError: 'tuple' object does not support item assignmentUse a tuple when the group is a single fixed thing, and a list when it is a collection that will grow or shrink.
It is the comma that makes a tuple, not the parentheses. That is why (5,) is a one-item tuple while (5) is just the number 5 in brackets.
single = (5,)not_a_tuple = (5)print(type(single).__name__, type(not_a_tuple).__name__)
pair = 1, 2print(pair)tuple int(1, 2)The parentheses are only needed to avoid ambiguity, so pair = 1, 2 builds a tuple without them. You have already seen this in the variables lesson, where a, b = b, a swapped two names, and in divmod(17, 5), which returns the pair (3, 2).
Immutability protects the tuple’s own slots, not whatever those slots refer to. A tuple that contains a list still lets you change that list. And because a tuple of immutable things can never change, it is hashable, so it can be a dictionary key or a set member, as the next lessons show.
Unpacking
x, y = point is unpacking: the names on the left receive the items on the right, in order. It works with any iterable, not only tuples.
point = (3, 4)x, y = pointprint(x, y)
quotient, remainder = divmod(17, 5)print(quotient, remainder)
low, high = min(4, 9, 2), max(4, 9, 2)print(low, high)3 43 22 9The number of names must match the number of items, otherwise Python raises ValueError:
p, q = [1, 2, 3]ValueError: too many values to unpack (expected 2, got 3)Two everyday idioms fall out of this. a, b = b, a swaps two names without a temporary variable: the right side is fully built as a tuple before any assignment happens. And a function can “return several values” by returning a tuple, which the caller unpacks, as divmod does. Strictly, such a function returns one tuple. Unpacking just makes it feel like two values. You will write your own functions like this in the functions module.
Star unpacking
Put a * in front of one name and it soaks up whatever the other names do not take. The starred name is always a list, even when the source is a string or a range, and it is an empty list when nothing is left over. Only one starred name is allowed per pattern.
first, *rest = [10, 20, 30, 40]print(first, rest)
*init, last = "abcd"print(init, last)
head, *middle, tail = range(1, 6)print(head, middle, tail)
only, *none = [7]print(only, none)10 [20, 30, 40]['a', 'b', 'c'] d1 [2, 3, 4] 57 []Unpacking in a loop and in nested patterns
You have already used unpacking without noticing: for position, letter in enumerate(...) unpacks each pair as the loop goes round. It works for any list of pairs:
pairs = [("Ada", 1815), ("Alan", 1912)]for name, year in pairs: print(name, year)Ada 1815Alan 1912Patterns can nest, with parentheses mirroring the shape of the data:
(a, b), c = (1, 2), 3print(a, b, c)1 2 3Spreading a list with *
The same star also works in the other direction. In a call, print(*numbers) spreads a list into separate arguments, and [0, *numbers, 4] splices one into a new list.
numbers = [1, 2, 3]print(*numbers)combined = [0, *numbers, 4]print(combined)1 2 3[0, 1, 2, 3, 4]Common pitfalls
- Forgetting the comma in a one-item tuple.
(5)is anint. Write(5,). - Expecting a tuple to be deeply frozen.
([1], 2)still lets you change the inner list. Immutability is one level deep. - Mismatched counts.
p, q = [1, 2, 3]raisesValueError. Add a starred name if the length varies. - Treating the starred name as a tuple. It is a list, whatever the source was.
- Using a tuple of mutable items as a dict key.
([1], 2)as a key raisesTypeError, because the list inside makes the whole tuple unhashable.
Turn the text "3,4" into the tuple (3, 4) of two integers, and print it. Use split(","), unpack the two pieces, and convert each with int.
Input: text = "3,4", then try " 10, -2 ". Expected output: (3, 4) for the first and (10, -2) for the second, because int ignores the spaces around a number. The file shows the first.
Show solution
text = "3,4"x_text, y_text = text.split(",")print((int(x_text), int(y_text)))(3, 4)Unpacking the result of split also checks the length for us. With the text "1,2,3" the unpacking raises ValueError: too many values to unpack (expected 2, got 3).
Given numbers = [4, 8, 15, 16, 23, 42], unpack the minimum, maximum and mean into three names low, high and mean in one assignment, and print them with the mean rounded to 2 decimals. Then use star unpacking to split ["Ada", "Ben", "Cy"] into a winner and the others, and print them.
Input: none. Expected output: 4 42 18.0 then Ada ['Ben', 'Cy'].
Show solution
numbers = [4, 8, 15, 16, 23, 42]low, high, mean = min(numbers), max(numbers), sum(numbers) / len(numbers)print(low, high, round(mean, 2))
winner, *others = ["Ada", "Ben", "Cy"]print(winner, others)4 42 18.0Ada ['Ben', 'Cy']The right side builds one tuple of three values, and the left side unpacks it in a single assignment.
Summary
- A tuple is an ordered, immutable sequence. The comma builds it, so a one-item tuple needs a trailing comma.
- Unpacking assigns items to names in one line:
x, y = point,a, b = b, a, and*restcollects the leftovers into a list. - Several values “returned together”, as from
divmod, are really one tuple.
Next: dictionaries.