A tuple is like a list, with one crucial difference: it cannot be changed after it’s created. We say tuples are immutable.

Use a tuple when you have a fixed group of values that belong together and shouldn’t change — coordinates, RGB colours, a row in a CSV.

Creating a tuple

point: tuple[int, int] = (3, 4)
rgb: tuple[int, int, int] = (255, 128, 0)
person: tuple[str, int, str] = ("Manikandan", 30, "admin")
empty: tuple[int, ...] = ()
single: tuple[int] = (42,)        # the comma matters!

A tuple:

  • Uses parentheses ( ).
  • Items are separated by commas.
  • The type hint tuple[T1, T2, ...] describes each position; tuple[T, ...] means “any length, all of type T”.

The single-item tuple needs a trailing comma. (42) is just the number 42 in parentheses. (42,) is a tuple containing one item.

Accessing items

Same as lists:

point: tuple[int, int] = (3, 4)
print(point[0])    # 3
print(point[1])    # 4
print(point[-1])   # 4

Slicing also works:

data: tuple[int, ...] = (10, 20, 30, 40, 50)
print(data[1:4])   # (20, 30, 40)  — note: a tuple, not a list

Tuples cannot be changed

point: tuple[int, int] = (3, 4)
point[0] = 10    # TypeError: 'tuple' object does not support item assignment

You can’t add, remove, or replace items. To “change” a tuple, build a new one:

point = (10, point[1])
print(point)   # (10, 4)

Why use tuples?

Three good reasons:

  1. Safety. When you pass a tuple around, no one can sneak in and modify it.
  2. Speed. Tuples are slightly faster than lists for the same operations.
  3. Intent. Using a tuple says “this is a fixed group of values, not a collection that might grow”.

A list of records is often a list of tuples:

people: list[tuple[str, int]] = [
    ("Alice", 30),
    ("Bob", 25),
    ("Carol", 35),
]

Each (name, age) pair is one record. Reordering or extending the list of records is normal — but each individual record shouldn’t change shape.

Packing and unpacking

This is one of Python’s nicest features. You can assign multiple variables from a tuple in one line:

point: tuple[int, int] = (3, 4)
x, y = point
print(x, y)   # 3 4

The variables on the left are matched to the values inside the tuple. This is called unpacking.

You can unpack any iterable — lists, strings, ranges:

a, b, c = [1, 2, 3]
first, second, third = "abc"

But the shapes must match:

x, y = (1, 2, 3)   # ValueError: too many values to unpack

The * in unpacking

To capture “the rest”, use *:

first, *rest = [1, 2, 3, 4, 5]
print(first)   # 1
print(rest)    # [2, 3, 4, 5]

*beginning, last = [1, 2, 3, 4, 5]
print(beginning)   # [1, 2, 3, 4]
print(last)        # 5

This is the same * you saw in *args, used here at the receiving end.

Swapping variables

The shortest variable swap in any language:

a: int = 1
b: int = 2

a, b = b, a
print(a, b)   # 2 1

Behind the scenes, Python packs b, a into a tuple and unpacks it into a, b.

Returning multiple values

Functions often return a tuple to give back several values:

def min_and_max(numbers: list[int]) -> tuple[int, int]:
    return min(numbers), max(numbers)


smallest, largest = min_and_max([3, 1, 4, 1, 5, 9, 2, 6])
print(smallest, largest)   # 1 9

You’ll see this in ML libraries all the time: train_loss, val_loss = train_step(...).

Named tuples (a teaser)

When a tuple’s positions start meaning specific things, a regular tuple gets awkward — you have to remember that position 2 is email and position 3 is role. The standard library has a fix:

from typing import NamedTuple


class User(NamedTuple):
    name: str
    age: int
    role: str


user = User("Manikandan", 30, "admin")
print(user.name, user.age)   # Manikandan 30

It’s a tuple with named fields. We’ll meet this again in Sections 12 (Classes) and 14 (Standard Library). For now, it’s enough to know it exists.

Tuples in the wild

You’ll meet tuples everywhere:

  • dict.items() returns tuples of (key, value)
  • enumerate() returns tuples of (index, value)
  • zip() (next section) returns tuples
  • ML models often return tuples of (predictions, attention) or similar

What’s next

Tuples are for fixed records. Next, sets — for collections where uniqueness matters.

Toggle theme (T)