Tuples
A tuple is an ordered collection that can't be changed after it's created. Tuples are used for fixed groups of related values — coordinates, RGB colours, database rows, multiple return values — and, because they're immutable, they can be used as dictionary keys and set members.
Creating tuples
point = (3, 4) rgb = (214, 51, 108) person = ("Ana", 31, "Lisbon") no_parens = 1, 2, 3 single = (42,) not_a_tuple = (42) empty = () print(type(no_parens), no_parens) print(type(single), type(not_a_tuple)) print(len(person), len(empty))
<class 'tuple'> (1, 2, 3) <class 'tuple'> <class 'int'> 3 0
It's actually the commas that make a tuple; parentheses are just grouping. That's why a one-item tuple needs a trailing comma: (42,).
Reading tuples
person = ("Ana", 31, "Lisbon", "engineer") print(person[0], person[-1]) print(person[1:3]) print("Lisbon" in person) print(person.index(31), person.count("Ana"))
Ana engineer (31, 'Lisbon') True 1 1
Indexing, slicing, in, len and looping all work just like lists. Tuples only have two methods: index and count.
Tuples are immutable
point = (3, 4) point[0] = 10
Traceback (most recent call last):
File "main.py", line 2, in <module>
point[0] = 10
~~~~~^^^
TypeError: 'tuple' object does not support item assignmentTo "change" a tuple, build a new one: point = (10, point[1]). Note that a tuple containing a mutable object, like a list, can still have that inner list modified.
Unpacking
Assigning a tuple to several names at once is called unpacking, and it's where tuples really shine:
point = (3, 4) x, y = point print(x, y) name, age, *rest = ("Ana", 31, "Lisbon", "engineer") print(name, age, rest) a, b = 1, 2 a, b = b, a print(a, b)
3 4 Ana 31 ['Lisbon', 'engineer'] 2 1
A starred name collects the leftovers into a list. Lesson 26 covers unpacking in more depth.
Returning several values
A function that "returns several values" actually returns a tuple, which the caller usually unpacks:
def min_max(numbers): return min(numbers), max(numbers) low, high = min_max([7, 2, 9, 4]) print(low, high) print(min_max([1, 5]))
2 9 (1, 5)
Tuples as dictionary keys
Because tuples are immutable (and hashable), they can be dictionary keys — useful for grids and composite keys:
board = {(0, 0): "X", (1, 1): "O", (2, 2): "X"}
print(board[(1, 1)])
print(board.get((0, 2), "empty"))
distances = {("Lisbon", "Porto"): 313, ("Lisbon", "Faro"): 278}
print(distances["Lisbon", "Porto"])
O empty 313
A list can't be used as a key — trying raises TypeError: cannot use 'list' as a dict key (unhashable type: 'list').
Named tuples
Positions like person[2] don't say much. A named tuple adds field names while staying a lightweight, immutable tuple:
from typing import NamedTuple class Point(NamedTuple): x: float y: float class City(NamedTuple): name: str population: int country: str = "Portugal" p = Point(3, 4) print(p.x, p.y, p) lisbon = City("Lisbon", 545_000) print(lisbon.name, lisbon.country) print(lisbon._replace(population=550_000))
3 4 Point(x=3, y=4) Lisbon Portugal City(name='Lisbon', population=550000, country='Portugal')
Named tuples print nicely, support default values, and can still be unpacked and indexed. For records that need to be changed, use a dataclass (lesson 40).
Tuple or list?
| Use a tuple when… | Use a list when… |
|---|---|
| The group has a fixed size and meaning per position (x, y) | You have a variable number of similar items |
| The data shouldn't change | You'll add, remove or reorder items |
| You need a dictionary key or set member | You need methods like append and sort |