Functions with Multiple Return Values
The syllabus names this separately because it surprises people coming from languages where a function returns exactly one thing.
def min_max(numbers):
return min(numbers), max(numbers)
low, high = min_max([4, 9, 1, 7])
print(low, high) # 1 9
What is actually happening
Python still returns one object — a tuple. The comma builds it:
def min_max(numbers):
return min(numbers), max(numbers)
result = min_max([4, 9, 1, 7])
print(result) # (1, 9)
print(type(result)) # <class 'tuple'>
low, high = result then unpacks that tuple, which is the same
unpacking met in the tuples topic. So "multiple return values" is really
"return a tuple, unpack it at the call" — and knowing that explains every
behaviour below.
Unpacking must match
low, high = min_max(data) # fine, 2 and 2
low, high, extra = min_max(data) # ValueError: not enough values
low = min_max(data) # low is the whole tuple (1, 9)
Use _ for a value you do not need:
_, high = min_max(data) # only the maximum wanted
Returning more than two
def stats(numbers):
total = sum(numbers)
return total, total / len(numbers), min(numbers), max(numbers)
total, avg, low, high = stats([10, 20, 30, 40])
# 100, 25.0, 10, 40
Past three or four values this becomes hard to read at the call site — nobody remembers which position is which. At that point return a dictionary instead:
def stats(numbers):
return {
"total": sum(numbers),
"average": sum(numbers) / len(numbers),
"min": min(numbers),
"max": max(numbers),
}
s = stats([10, 20, 30, 40])
print(s["average"]) # 25.0 — self-describing
The tuple version is shorter; the dictionary version is readable six months later. For two or three values use a tuple, beyond that a dictionary.
Why this matters for decomposition
Multiple returns let a function answer a complete question in one call instead of being split artificially:
# Awkward: two functions, the list scanned twice
smallest = find_min(data)
largest = find_max(data)
# Better: one pass, one call
smallest, largest = min_max(data)
That connects back to decomposition — a function should do one nameable job, and "find the smallest and largest" is one job even though it produces two answers.
Swapping, revisited
The swap from the tuples topic is this same mechanism:
a, b = b, a
The right-hand side builds the tuple (b, a) first, then unpacks it
into a and b. Because the tuple captures both original values before
either name is reassigned, no temporary variable is needed — the problem
that took three lines in Module 2 pseudocode.