Learning Goals
3 minBy the end of this lesson you can:
- Unpack a tuple into separate named variables in one line —
day, month, year = dob. - Swap the values of two variables without a temp variable —
a, b = b, a. - Write a function that returns more than one value, and unpack the result at the call site.
Warm-Up
5 minYesterday you built tuples like (12, 8, 2014) and read items out with dob[0], dob[1], dob[2]. That works — but it's noisy. The reader has to remember "index 0 was the day, index 1 was the month…" every time.
Predict what this prints:
dob = (12, 8, 2014) day, month, year = dob print(day) print(month) print(year)
Show the answer
12 8 2014
One line did the work of three. Python unpacked the three-item tuple into three named variables.
If you have a tuple of N items and N names on the left, Python pairs them up by position. The names are yours to choose.
New Concept · Three Uses of Unpacking
14 minUse 1 · Naming the pieces of a tuple
The simple case. Left and right must have the same number of items.
point = (10, 20) x, y = point print("x =", x, " y =", y) # → x = 10 y = 20
If the counts don't match, Python crashes — clearly:
x, y = (10, 20, 30) # ValueError: too many values to unpack (expected 2)
Use 2 · Swapping two variables in one line
The famous trick. No temp variable, no tmp, no muddle.
a = "apple" b = "banana" a, b = b, a print(a, b) # → banana apple
The right-hand side b, a builds a temporary tuple ("banana", "apple"); Python then unpacks it into a, b on the left. Two seats, swapped, in one move.
Use 3 · Unpacking inside a for loop
You already used this in the sports-day example — here it is on its own:
scores = [ ("Aisyah", 92), ("Wei Jie", 87), ("Priya", 95), ] for name, score in scores: print(name, "->", score)
Aisyah -> 92 Wei Jie -> 87 Priya -> 95
Each item in the list is a two-tuple. The loop unpacks it into name and score on every pass. Much nicer than scores[i][0], scores[i][1].
Use 4 · Functions that return more than one thing
A function can return a tuple — and the caller can unpack it. To Python, returning "more than one value" just is returning a tuple.
def min_and_max(numbers): return min(numbers), max(numbers) low, high = min_and_max([5, 9, 2, 7, 1, 8]) print("Lowest :", low) print("Highest:", high) # Lowest : 1 # Highest: 9
The return line has two values separated by a comma — Python wraps them into a tuple. The call site unpacks the tuple back into two names. Clean.
Forgetting to unpack is fine too — you just get the tuple back as one variable:
pair = min_and_max([5, 9, 2, 7, 1, 8]) print(pair) # → (1, 9) print(pair[0]) # → 1 print(pair[1]) # → 9
Use whichever fits the reader best. Two named variables for two distinct roles; the tuple if you're just passing it along.
Worked Example · The Stats Pack
12 minThe story
Cikgu Hadi keeps a list of marks from a maths quiz. He always wants three numbers back at once: the lowest, the highest and the average. We'll write quiz_stats() that returns all three in one go.
Save as quiz_stats.py:
Code
# quiz_stats.py — return three stats in one go def quiz_stats(marks): low = min(marks) high = max(marks) avg = sum(marks) / len(marks) return low, high, avg class_marks = [62, 88, 75, 49, 95, 71, 80, 67] low, high, avg = quiz_stats(class_marks) print("Lowest :", low) print("Highest:", high) print("Average:", avg)
Output
Lowest : 49 Highest: 95 Average: 73.375
What if we forget to unpack?
Watch the difference:
stats = quiz_stats(class_marks) print(stats) # → (49, 95, 73.375) print("Lowest is", stats[0]) # → Lowest is 49
Same return value — just held as one bundled tuple instead of three named pieces. Both forms are valid; named variables are usually easier to read.
Mini-version with swap
Add this at the bottom of the file:
# A tiny detour — swap two students' marks in one line a_mark = 75 b_mark = 80 a_mark, b_mark = b_mark, a_mark print("After swap:", a_mark, b_mark) # → After swap: 80 75
One line. No tmp = a_mark, no three-step shuffle. The right-hand side becomes a tuple (80, 75), and the left-hand side unpacks it.
If a function returns three values and you only catch two — a, b = quiz_stats(class_marks) — you'll get ValueError: too many values to unpack (expected 2). Read the error: it tells you exactly how many items came out of the tuple, and how many names you supplied.
Try It Yourself
13 minThree exercises. Try each one before opening the hint.
Start with point = (8, 15). Unpack it into x and y in one line. Print the message The point is at x = 8, y = 15.
Hint
point = (8, 15) x, y = point print("The point is at x =", x, ", y =", y)
Two students need to switch places. Start with front = "Aisyah" and back = "Wei Jie". Print them, swap them in one line, print them again.
Hint
front = "Aisyah" back = "Wei Jie" print("Before:", front, "|", back) front, back = back, front print("After :", front, "|", back)
Write a function divide_with_remainder(a, b) that returns the quotient (a // b) and the remainder (a % b) as two values. Call it with 17, 5 and unpack the result into q, r. Print both.
Hint
def divide_with_remainder(a, b): return a // b, a % b q, r = divide_with_remainder(17, 5) print("Quotient :", q) # → 3 print("Remainder:", r) # → 2
Notice the return line: two values, one comma, no brackets — Python builds the tuple for you.
Mini-Challenge · The Top-3 Reporter
8 minBuild top3.py. It scans a list of (name, score) tuples and reports the top three students. You'll use every move from today.
Your file must:
- Start with at least five
(name, score)tuples in a list. - Use
sorted(students, key=lambda s: s[1], reverse=True)to rank by score — you don't need to understandlambdadeeply yet, just type it as a recipe. - Loop the top three with
for name, score in ranked[:3]— unpacking inside the loop. - Print each top student on its own line, like
1. Aisyah — 95. - Write a function
best_and_worst(students)that returns the name of the highest scorer and the name of the lowest scorer (two values). Unpack the result and print both.
Stretch goal. Show the difference between the best and worst scores in a single print line, using the function's return.
Show one possible solution
# top3.py — leaderboards and multi-return students = [ ("Aisyah", 92), ("Wei Jie", 87), ("Priya", 95), ("Iman", 70), ("Aizat", 81), ] ranked = sorted(students, key=lambda s: s[1], reverse=True) print("Top three:") i = 1 for name, score in ranked[:3]: print(i, ".", name, "—", score) i = i + 1 def best_and_worst(students): ranked = sorted(students, key=lambda s: s[1], reverse=True) return ranked[0][0], ranked[-1][0] best, worst = best_and_worst(students) print() print("Best on the day :", best) print("Worst on the day:", worst) # Stretch — score gap def best_score_and_worst_score(students): ranked = sorted(students, key=lambda s: s[1], reverse=True) return ranked[0][1], ranked[-1][1] hi, lo = best_score_and_worst_score(students) print("Score gap :", hi - lo)
Non-negotiables: a list of (name, score) tuples, the sorted(... key=lambda ..., reverse=True) line as a recipe, the unpacking for name, score in ... loop, and one function that returns two values which you unpack on a single line. Your lambda understanding will deepen in Level 3.
Recap
3 minTuple unpacking is the act of spreading a tuple into multiple named variables in one move. It cleans up indexing (x, y = point), it enables the elegant one-line swap (a, b = b, a), it tidies for loops over (name, score)-style data, and it lets functions return several values without using a class or a list. The left-hand and right-hand sides must agree on the count — otherwise Python crashes with a clear ValueError.
Vocabulary Card
- unpacking
- Spreading the items of a tuple (or list) into separate named variables in one assignment.
- multiple return
- A function that uses
return a, b— really one return value, a tuple, that the caller can unpack. - swap idiom
a, b = b, a— Python's built-in "switch two values" one-liner.
Homework
4 minSave a new file address.py. Write a function parse_address(line) that takes one string like "Aisyah, 12, Kuala Lumpur" and returns three values — name, age (as an int), city.
Inside the function use line.split(", ") to split the string into three parts. Convert the age to an integer. Return the three things — Python will bundle them as a tuple.
In the main program:
- Hand-craft three address lines in a list.
- Loop through the list. For each line, call
parse_addressand unpack the result intoname, age, city. - Print each person as
name (age) lives in city.
Stretch. Add a fourth address line with the wrong number of commas. See what happens. Then guard against it by checking if line.count(", ") == 2 before calling the function.
Sample · address.py
# address.py — parse a line, return three things, unpack them def parse_address(line): parts = line.split(", ") name = parts[0] age = int(parts[1]) city = parts[2] return name, age, city lines = [ "Aisyah, 12, Kuala Lumpur", "Wei Jie, 13, Penang", "Priya, 11, Ipoh", ] for line in lines: name, age, city = parse_address(line) print(name, "(", age, ")", "lives in", city) # Stretch — guarded bad = "Iman, 12, Johor, extra" if bad.count(", ") == 2: name, age, city = parse_address(bad) print(name, "lives in", city) else: print("Skipped — wrong shape:", bad)
Non-negotiables: a function whose return hands back three values, a call site that unpacks into name, age, city, and a loop that processes a list of three address lines.