livepython.net
CHAPTER 14Tuples and Sets
14.2  UNPACKING

Tuple Unpacking in Python: a, b = pair

Tuple Unpacking: Many Variables in One Line

Unpacking means taking the items out of a tuple and putting each one into its own variable, all in one line.

PYTHONedit me
person = ("Sunny", 25, "Pune")
name, age, city = person
print(name)
print(age)
print(city)
OUTPUT
Sunny
25
Pune

Think of it like unpacking a lunch box with three compartments onto three plates: the first compartment goes on the first plate, the second on the second, and so on.

The rules

  • The variable names go on the left, separated by commas. The tuple goes on the right.
  • The first name gets the first item, the second name gets the second item, and so on.
  • The number of names must match the number of items.
  • It works with lists too: a, b = [1, 2].

Good: names instead of indexes

Without unpacking, you'd pick out every item by its index:

PYTHONedit me
person = ("Sunny", 25)
name = person[0]
age = person[1]
print(name, "is", age)
OUTPUT
Sunny is 25

It works, but it's two lines, and person[1] doesn't say what's inside. Unpacking does both jobs at once, and the names explain the data:

PYTHONedit me
person = ("Sunny", 25)
name, age = person
print(name, "is", age)
OUTPUT
Sunny is 25

Avoid: the wrong number of names

If the counts don't match, Python stops with a ValueError:

PYTHONedit me
point = (3, 5, 9)
x, y = point
OUTPUT
ValueError: too many values to unpack (expected 2, got 3)
PYTHONedit me
point = (3, 5)
x, y, z = point
OUTPUT
ValueError: not enough values to unpack (expected 3, got 2)

Read the message like a sentence: "I expected 2 names' worth of values, but I got 3." Count the names on the left, count the items on the right, and make them equal.

Common beginner doubt: "Does unpacking empty the tuple?" No! The tuple stays exactly as it was. The variables only get copies of its values, so you can still use person afterwards.

name, age = person: one name per item, in order.

your turnPredict the output

What will this print?

size = (1920, 1080) width, height = size print(height)
Your turn! What will this code show on the screen?
your turnPick the right idea

What happens when this line runs?

a, b = (1, 2, 3)
Think about it, then pick one.

Swapping Two Variables Is Tuple Unpacking

In chapter 4 you swapped two values with a, b = b, a. Now you can see what really happens: it's packing and unpacking in one line.

PYTHONedit me
a = "tea"
b = "coffee"
a, b = b, a
print(a, b)
OUTPUT
coffee tea

Step by step

  1. Python works out the right side first. b, a has a comma, so it packs the two values into a tuple: ("coffee", "tea").
  2. Then the left side unpacks that tuple: a gets "coffee" and b gets "tea".

Here is the same swap in slow motion, with the tuple in its own variable:

PYTHONedit me
a = "tea"
b = "coffee"
pair = b, a
print(pair)
a, b = pair
print(a, b)
OUTPUT
('coffee', 'tea')
coffee tea

Think of it like swapping two cups of drinks with a tray: first both drinks go onto the tray, then each cup is filled from the tray. Nothing is poured away, so nothing is lost.

Why the two-line swap fails

Without a tuple, the first line wipes out a value before it's saved:

PYTHONedit me
a = 1
b = 2
a = b
b = a
print(a, b)
OUTPUT
2 2

a = b replaced the 1, so b = a copied the 2 back. The packed tuple keeps both old values safe until the unpacking is done.

More than two

Packing and unpacking work with any number of values, as long as the counts match. Here three values move one place to the left:

PYTHONedit me
x, y, z = 1, 2, 3
x, y, z = y, z, x
print(x, y, z)
OUTPUT
2 3 1

The three forms

You writeWhat happens
t = 1, 2packing: t becomes the tuple (1, 2)
a, b = tunpacking: a gets 1, b gets 2
a, b = 1, 2both: pack the values, then unpack them
a, b = b, aboth: the swap

So name, age = "Sunny", 25 from chapter 4 was a tuple all along. You've been using tuples since chapter 4 without knowing it!

a, b = b, a packs both values into a tuple first, then unpacks them: nothing is lost.

your turnFill the gap

Move each value one place to the right

x, y, z = 1, 2, 3 x, y, z = ? print(x, y, z)

It should print: 3 1 2

Which piece makes this code work?
your turnPredict the output

Remember chained assignment from chapter 4?

x = y = 0 x = 5 print(x, y)
Your turn! What will this code show on the screen?

Unpacking in a for Loop: Lists of Pairs

A list can hold tuples, and a for loop can unpack each one as it goes. Write two names between for and in: for name, score in scores:.

PYTHONedit me
scores = [("Sunny", 82), ("Rocky", 45), ("Lucky", 91)]
for name, score in scores:
    print(name, "scored", score)
OUTPUT
Sunny scored 82
Rocky scored 45
Lucky scored 91

Each round, the loop takes the next tuple, like ("Sunny", 82), and unpacks it: name gets "Sunny" and score gets 82.

Think of it like a pile of cards with a name on the front and a score on the back. Each round you pick up one card and read both sides at once.

Without unpacking

You could take each tuple whole and use indexes:

PYTHONedit me
scores = [("Sunny", 82), ("Rocky", 45)]
for pair in scores:
    print(pair[0], "scored", pair[1])
OUTPUT
Sunny scored 82
Rocky scored 45

It works, but pair[0] and pair[1] tell the reader nothing. With unpacking, the names say what's inside.

The rules

  • Every tuple in the list must have as many items as there are names between for and in.
  • Pick names that describe the pair: name, score, not a, b.
  • Inside the loop, use them like any variable: totals, counters and if work as in chapter 10.
PYTHONedit me
scores = [("Sunny", 82), ("Rocky", 45), ("Lucky", 91)]
total = 0
for name, score in scores:
    total += score
    if score < 50:
        print(name, "needs help")
print("Total:", total)
OUTPUT
Rocky needs help
Total: 218

Dictionaries do this too

In chapter 13 you looped over a dictionary with .items(). Now you know why two names work there: every item it gives you is a (key, value) tuple, unpacked into two names.

PYTHONedit me
prices = {"tea": 10, "cake": 25}
for item, price in prices.items():
    print(item, price)
OUTPUT
tea 10
cake 25

Avoid: a pair with a missing value

PYTHONedit me
pairs = [("Sunny", 82), ("Rocky",)]
for name, score in pairs:
    print(name, score)
OUTPUT
Sunny 82
ValueError: not enough values to unpack (expected 2, got 1)

The first round worked. The second tuple has only one item, so two names can't be filled.

for name, score in pairs: unpacks one pair every round.

your turnOrder the lines

Put the lines in order to print 35

  1. total += price
  2. total = 0
  3. print(total)
  4. for item, price in [("tea", 10), ("cake", 25)]:
These lines are mixed up. Put them back in order, then press Check.
your turnType the output

Type what this prints

pairs = [("a", 1), ("b", 2)] for letter, n in pairs: print(letter * n)
Read the code line by line, then type the output exactly.

Index and Item Together with enumerate()

Sometimes you need each item and its position. enumerate() gives you both, as a (position, item) tuple that you unpack in the for loop.

PYTHONedit me
names = ["Sunny", "Rocky", "Lucky"]
for i, name in enumerate(names):
    print(i, name)
OUTPUT
0 Sunny
1 Rocky
2 Lucky

Think of it like runners in a race getting a number as they cross the line: each runner comes with a number attached, and you read both at once.

What enumerate() really gives

Turn it into a list to see inside. It's a list of tuples, just like the pairs in the last lesson:

PYTHONedit me
print(list(enumerate(["a", "b"])))
OUTPUT
[(0, 'a'), (1, 'b')]

Start counting from 1

People count from 1, not 0. Give enumerate() a second value to choose the start:

PYTHONedit me
tasks = ["wash", "cook", "shop"]
for number, task in enumerate(tasks, 1):
    print(f"{number}. {task}")
OUTPUT
1. wash
2. cook
3. shop

The rules

  • enumerate(x) counts from 0; enumerate(x, 1) counts from 1.
  • The position comes first, the item second: for i, item in ....
  • It works on lists, tuples and strings.

The old way

In chapter 10 you could get the same result with range() and an index:

PYTHONedit me
names = ["Sunny", "Rocky"]
for i in range(len(names)):
    print(i, names[i])
OUTPUT
0 Sunny
1 Rocky

It works, but enumerate() is shorter, and you never have to write names[i].

Common mistake: the names the wrong way round

Swap the two names, and there's no error, only a wrong result. The position goes into name and the item into i:

PYTHONedit me
names = ["Sunny", "Rocky"]
for name, i in enumerate(names, 1):
    print(name, "is", i)
OUTPUT
1 is Sunny
2 is Rocky

Remember the order: position, then item, the same order as in (0, 'a').

for i, item in enumerate(my_list, 1): the position and the item, unpacked together.

your turnPredict the output

What will this print?

for n, ch in enumerate("hi", 1): print(n, ch)
Your turn! What will this code show on the screen?
your turnFill the gap

Number the menu from 1

for ? in enumerate(["tea", "cake"], 1): print(n, item)

It should print: 1 tea 2 cake

Which piece makes this code work?

Practice: Unpacking

Solve these to lock in what you learned in this topic. Each one runs in your browser.

  1. 122.Python Program to Swap Two Numbers Using Tuple UnpackingEasySolve
  2. 123.Python Program to Print a Marks Report from a List of TuplesMediumSolve