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

PY create.py
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))
Output
<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

PY read.py
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"))
Output
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

PY immutable.py
point = (3, 4)
point[0] = 10
Output
Traceback (most recent call last):
  File "main.py", line 2, in <module>
    point[0] = 10
    ~~~~~^^^
TypeError: 'tuple' object does not support item assignment

To "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:

PY unpack.py
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)
Output
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:

PY return.py
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]))
Output
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:

PY keys.py
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"])
Output
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:

PY named.py
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))
Output
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 changeYou'll add, remove or reorder items
You need a dictionary key or set memberYou need methods like append and sort

Try it yourself

Try it yourself
Console output