Unpacking a Sequence
A list holds several values under one name, and getting them out has always meant asking for them one at a time — point[0], point[1]. There is a line that does the whole job at once, and it is one of the small things that makes Python look like Python.
1Several names on the left of one =
# the long way, and the short way
point = [3, 7]
x = point[0]
y = point[1]
print('the long way: ', x, y)
x, y = point
print('the short way:', x, y)the long way: 3 7 the short way: 3 7
x, y = point is called unpacking: the items of the sequence on the right are handed out to the names on the left, one each, in order. It is one statement, not two — the = in the middle is the ordinary assignment operator with more than one name in front of it.
x = point gives x the whole list. x, y = point takes the list apart. The only difference is a comma and a second name, and that is worth reading twice, because it is the difference between a list and two numbers.2Watch the items being handed out
Step through it below, and then step through the two broken cases — they are the whole reason this page has a widget. Once you have watched the items being dealt out one per name, both error messages say exactly what they mean.
Watch the items being dealt out — and watch what happens when the counts do not match.
Python checks nothing yet. It simply starts handing the items of [10, 20, 30] out to the names on the left, one each, in order.
3The one rule: the counts must match
Too many items and some have nowhere to go. Too few and some names are left waiting. Python refuses both, and the two messages are worth recognising on sight:
# three values, two names
values = [10, 20, 30]
a, b = valuesTraceback (most recent call last):
File "too_many.py", line 5, in <module>
a, b = values
^^^^
ValueError: too many values to unpack (expected 2)# two values, three names
values = [10, 20]
a, b, c = valuesTraceback (most recent call last):
File "too_few.py", line 5, in <module>
a, b, c = values
^^^^^^^
ValueError: not enough values to unpack (expected 3, got 2)a holds whatever it held before, or does not exist.The messages are precise, and reading them is quicker than guessing: too many values means the right-hand side was longer; not enough values (expected 3, got 2) tells you both numbers. Either way the fix is the same — count the names, count the items, and make them agree.
4It works on any sequence
Nothing in the idea is about lists. Anything with items in order can be unpacked — a list, a tuple, even a string, whose items are its characters:
# it works on anything with items in order
a, b, c = [10, 20, 30]
print(a, b, c)
p, q, r = (1, 2, 3)
print(p, q, r)
first, second, third = 'abc'
print(first, second, third)10 20 30 1 2 3 a b c
'abc' has three items — 'a', 'b', 'c' — so it unpacks into three names, exactly as the strings chapter said it would when it called a string a sequence. Try it with a four-letter word and you get too many values to unpack.5Where it earns its keep
Three places, all of which you have already met and worked round:
name, age = line.split()split() hands back a list of pieces, and unpacking gives each piece its own name in the same line. Two pieces expected, two names — and a line with three words raises ValueError, which is arguably better than silently ignoring one.
for name, marks in students:When a list holds small lists, the loop variable can be unpacked as it arrives. That is the next-but-one page, and it is the one you will use most.
x, y = y, xThe line the course has used twice without explaining. It is unpacking on the left and something else on the right — which is the next page.
# one line of input, split and unpacked
line = input('Enter your name and age, separated by a space: ')
name, age = line.split()
print('Name:', name)
print('Age next year:', int(age) + 1)Enter your name and age, separated by a space: Asha 16 Name: Asha Age next year: 17
name, age = line.split()split() gives ['Asha', '16'] and the two names take one piece each. Both pieces are still TEXT — unpacking moves values about, it never converts them, which is why int() is still needed on the next line.
Asha Kumari 16 and split() gives three pieces for two names: ValueError: too many values to unpack (expected 2). That is unpacking doing its job — the program said it wanted exactly two, and it did not get two.6Recap
The items of the sequence on the right are handed to the names on the left, left to right. It is one statement, not several.
ValueError either way — too many values, or not enough (and it tells you both numbers). Nothing is assigned when it fails.
Lists, tuples, strings, and anything else with items in order. A three-letter string unpacks into three names.
name, age = line.split() leaves age as text. int() is still needed before any arithmetic.
values = [10, 20, 30] and then a, b = values. What happens?
What is the difference between x = point and x, y = point?
After name, age = line.split(), what type is age?