Tuples
Fixed collections that can't change
In this lesson
A tuple is like a list, but immutable — once created, it can’t be changed. That sounds limiting, but it’s exactly what you want for groups of values that belong together and shouldn’t be edited.
Explain it like I’m 5
A tuple is a sealed package of items. You can look inside and see everything, but you can’t add, remove, or swap what’s in it.
Tuples vs lists
You write a tuple with parentheses (or just commas): point = (3, 4). Reading works exactly like a list — point[0] is 3. The difference is you can’t change it: point[0] = 5 raises an error. Use a list when the collection will grow or change; use a tuple when it’s a fixed group, like a coordinate or an RGB colour.
point = (3, 4)
print(point[0])
print(point[1])
print("x and y:", point)
3 4 x and y: (3, 4)
Why immutability is a feature
Because a tuple can’t change, you can trust its contents won’t be modified by accident elsewhere in your program. Tuples can also be used as dictionary keys (lists can’t), and they signal intent: ‘these values belong together as one fixed record’.
Unpacking: pulling a tuple apart
Unpacking assigns each item to its own variable in one line: x, y = point sets x = 3 and y = 4. This is everywhere in Python — it’s how enumerate() gives you index and item, and how you swap two variables with a, b = b, a.
person = ("Ada", 36, "London")
name, age, city = person
print(name, "is", age, "and lives in", city)
Ada is 36 and lives in London
a = 1
b = 2
a, b = b, a
print("a =", a, "b =", b)
a = 2 b = 1
Unpack the tuple into r, g, b and print each colour channel on its own line.
colour = (255, 160, 0)
# unpack into r, g, b
print("Red:", r)
print("Green:", g)
print("Blue:", b)
One line does it: r, g, b = colour. The three variables match the three items in order.
colour = (255, 160, 0)
r, g, b = colour
print("Red:", r)
print("Green:", g)
print("Blue:", b)
Red: 255
Green: 160
Blue: 0
Returning several values
A function can ‘return multiple values’ by returning a tuple: return minimum, maximum. The caller unpacks them: low, high = get_range(data). It feels like getting two results, but under the hood it’s one tuple being unpacked.
def high_and_low(numbers):
return min(numbers), max(numbers)
low, high = high_and_low([4, 9, 1, 7])
print("low:", low)
print("high:", high)
low: 1 high: 7
Star unpacking: grab ‘the rest’
When you unpack, a starred name scoops up everything left over into a list. first, *rest = [1, 2, 3, 4] puts 1 in first and [2, 3, 4] in rest. The star can sit at the end or the start: *head, last grabs the final item and bundles the rest.
It’s a clean way to peel the first or last element off a sequence while keeping the remainder in one piece.
first, *rest = [10, 20, 30, 40]
print(first)
print(rest)
*head, last = [10, 20, 30, 40]
print(last)
print(head)
10 [20, 30, 40] 40 [10, 20, 30]
Common mistake: Trying to change a tuple
Tuples look like lists, so it’s tempting to write t[0] = 9 — but tuples are immutable and this raises a TypeError.
If you need to change items, use a list instead. If you only need a tweaked version, build a new tuple from the old one.
What is the key difference between a tuple and a list?
Tuples are immutable; lists are mutable. Both keep their items in order.
What does a, b = (10, 20) do?
This is tuple unpacking — each variable receives the matching item.
Mini exercise (medium)
Write a function min_max(numbers) that returns the smallest and largest values as a tuple, then unpack and print them for [4, 9, 1, 7].
Do it here. Finish the code below and press Run to try your answer right in the browser — no setup needed.
def min_max(numbers):
# return (smallest, largest) as a tuple
return (0, 0)
low, high = min_max([4, 9, 1, 7])
print(low, high)
Use the built-ins min() and max(), and return min(numbers), max(numbers).
def min_max(numbers):
return min(numbers), max(numbers)
low, high = min_max([4, 9, 1, 7])
print(low, high)
1 9
assert min_max([4, 9, 1, 7]) == (1, 9), "min_max should return 1 and 9"
print("✓ Correct!")