Unpacking
Picture two cups: tea in the left one, coffee in the right. You need to swap the drinks. If you pour the coffee into the left cup right away, the tea is lost. You cannot do it without a third, empty cup.
Variables are the same. The two lines a = b and b = a are not enough. After the first, the old value of a is lost, and both variables refer to the same number. In Python, a swap is written in one line:
a = 1
b = 2
a, b = b, a
print(a, b) # 2 1Here a tuple plays the part of the third cup. Let's see how it appears and where it goes afterwards.
How unpacking works
Recall the sealed pack from the previous lesson. The line a, b = b, a first builds such a pack and then opens it. There are two steps:
- To the right of
=stands the tupleb, a. Python computes it in full from the current values and gets(2, 1). - Then unpacking spreads the tuple's items over the names on the left in order: the first to
a, the second tob.
Until the right side is fully computed, no name on the left changes. That is why the old value of a is not lost: it is already in the pack when a gets its new value.
Press "Next step" and watch the variables. On every unpacking line, they change only after the whole tuple on the right is ready.
1def divide(a, b):2 return a // b, a % b3 4 5q, r = divide(17, 5)6print(q, r)7a, b = 1, 28a, b = b, a9print(a, b)10a, b = b, a + b11print(a, b)
To the right of = is the call divide(17, 5). The names q and r do not exist yet.
The same order explains returning several values from a function:
def divide(a, b):
return a // b, a % b
q, r = divide(17, 5)
print(q, r) # 3 2
a, b = 1, 2
a, b = b, a + b
print(a, b) # 2 3Let's go through the example line by line:
divide(17, 5)returns one object, the tuple(3, 2).q, r = …spreads it at once:qgets3, andrgets2.- In the line
a, b = b, a + b, the expressiona + buses the olda, which is1. - So
bgets3, not4, and the program prints2 3.
Any sequence can stand on the right: x, y, z = [10, 20, 30] unpacks a list, and first, second = "ok" unpacks a string.
Interviewers often ask you to swap two variables without a third one. The answer is a, b = b, a. Explain why it works, too: the right side is computed in full before the first assignment.
Here the pack picture simplifies a little. For two or three names, the interpreter optimizes the swap and does not build a real tuple. But the order is the same: everything on the right is computed before any name on the left changes.
A starred name
When there are more items than names, you can mark one name with a star *. Such a name is like a bag that collects all the tiles the other names did not get:
first, *rest = [5, 6, 7, 8]
print(first, rest) # 5 [6, 7, 8]
head, *middle, tail = (1, 2, 3, 4)
print(head, middle, tail) # 1 [2, 3] 4
x, *others = [9]
print(x, others) # 9 []What each line does:
first, *rest:firsttakes the first item, andresttakes all the others;head, *middle, tail: the end items get plain names, and the middle goes tomiddle;x, *others = [9]: there are no extra items, andothersgets an empty list.
This is how the first item is split from the rest when the length of the sequence is not known in advance. For example, cmd, *files = "copy a.txt b.txt".split() puts the command in cmd and the file names in the list files.
A starred name always gets a list, even when the right side is a tuple. The star can go on the first, a middle or the last name, but on only one. With two stars, Python cannot tell how to split the items between them and reports a SyntaxError.
Common mistake
The number of names on the left does not match the number of items on the right:
point = (3, 4, 5)
x, y = point # ✗ValueError: too many values to unpack (expected 2)Without a star, there must be exactly as many names as items. The number in expected 2 is the count of names on the left. When there are more names, the message is different: ValueError: not enough values to unpack (expected 3, got 2).
To fix it, add a third name: x, y, z = point. If you do not need the other items, use a star: x, y, *rest = point.
Key points
- In unpacking, Python first computes the whole right side, then spreads the items over the names left to right.
- That is why
a, b = b, aswaps the values andreturn q, rreturns one tuple. - A starred name collects the extra items into a list, possibly an empty one.
- Without a star, the number of names must match the number of items, or you get a
ValueError.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.