Python Tuples: Packing, Unpacking and Named Tuples

By Engr. Henry Akpan

The List That Cannot Change

Python has several ways to group values together, and the tuple is the simplest. A tuple looks like a list written with round brackets, but once it is created it cannot be changed. That restriction turns out to be very useful: tuples are safer for data that should stay fixed, they can be used as dictionary keys, and they make it easy to return several values from a function. This tutorial covers Python tuples from the basics to practical patterns: creating tuples, indexing and slicing, immutability, packing and unpacking, swapping variables, returning multiple values, tuples as dictionary keys, and named tuples for readable records. Every example has been run, and its output is shown.

Creating Python Tuples

Write the values separated by commas, usually inside round brackets:

point = (3, 4)
student = ("Ada", "Physics", 4.52)
empty = ()
single = (7,)      # the comma makes it a tuple
not_a_tuple = (7)  # just the number 7 in brackets
print(point, student)
print(type(single).__name__, type(not_a_tuple).__name__)
print(len(student))

Output:

(3, 4) ('Ada', 'Physics', 4.52)
tuple int
3

It is the comma, not the brackets, that makes a tuple. A one-item tuple needs a trailing comma, which is a common source of bugs. You can also build a tuple from any iterable with tuple(), for example tuple("abc") gives ('a', 'b', 'c').

Indexing, Slicing and Looping

Tuples support the same read-only operations as lists:

days = ("Mon", "Tue", "Wed", "Thu", "Fri")
print(days[0], days[-1])
print(days[1:4])
print("Wed" in days, days.index("Thu"), days.count("Mon"))
for i, d in enumerate(days, start=1):
    if i % 2 == 1:
        print(i, d)

Output:

Mon Fri
('Tue', 'Wed', 'Thu')
True 3 1
1 Mon
3 Wed
5 Fri

Tuples have only two methods, count and index, because every other list method (append, sort, remove and so on) would change the data.

Immutability

Trying to change an item raises an error:

point = (3, 4)
try:
    point[0] = 10
except TypeError as e:
    print("Error:", e)

Output:

Error: 'tuple' object does not support item assignment

To "change" a tuple, build a new one:

point = (10,) + point[1:]
print(point)

Output:

(10, 4)

A subtle point: a tuple cannot have its items replaced, but if an item is itself mutable, such as a list, that inner object can still change. The tuple holds references to objects, and it is the references that are fixed.

record = ("Bola", [70, 85])
record[1].append(90)
print(record)

Output:

('Bola', [70, 85, 90])

Packing and Unpacking

Writing several values separated by commas packs them into a tuple. Assigning a tuple to several names unpacks it:

coords = 6.45, 3.39        # packing (Lagos, roughly: latitude, longitude)
lat, lon = coords          # unpacking
print(lat, lon)

a, b = 1, 2
a, b = b, a                # swap without a temporary variable
print(a, b)

Output:

6.45 3.39
2 1

The swap works because the right-hand side b, a is packed into a tuple first, and only then unpacked into a and b.

Extended unpacking with a star collects "the rest" into a list:

scores = (55, 72, 64, 90, 81)
first, *middle, last = scores
print(first, middle, last)
head, *_ = scores          # _ is a conventional name for values you ignore
print(head)

Output:

55 [72, 64, 90] 81
55

Unpacking also works in for loops, which is why for key, value in d.items() and for i, x in enumerate(items) read so naturally.

Returning Multiple Values from a Function

A function can return a tuple, and the caller can unpack it in one line:

def min_max_mean(values):
    return min(values), max(values), sum(values) / len(values)

lo, hi, avg = min_max_mean([4.2, 3.5, 4.8, 3.9])
print(lo, hi, round(avg, 2))

q, r = divmod(17, 5)   # a built-in that returns a tuple
print(q, r)

Output:

3.5 4.8 4.1
3 2

Tuples as Dictionary Keys and in Sets

Because tuples are immutable (when their items are), they are hashable and can be used as dictionary keys or set members. Lists cannot. This is perfect for coordinates and compound keys:

seats = {("A", 1): "Chidi", ("A", 2): "Fatima", ("B", 1): "Musa"}
print(seats[("A", 2)])

visited = {(0, 0), (0, 1)}
visited.add((1, 1))
print((0, 1) in visited, len(visited))

try:
    bad = {[0, 0]: "x"}
except TypeError as e:
    print("Error:", e)

Output:

Fatima
True 3
Error: unhashable type: 'list'

Sorting and Comparing Tuples

Tuples compare item by item from the left, like words in a dictionary. This makes sorting by several criteria easy:

results = [("Emeka", 72), ("Ada", 85), ("Musa", 72), ("Zainab", 90)]
# highest score first, then alphabetical by name for ties
ranked = sorted(results, key=lambda r: (-r[1], r[0]))
for name, score in ranked:
    print(name, score)
print((1, 2, 3) < (1, 3, 0))

Output:

Zainab 90
Ada 85
Emeka 72
Musa 72
True

Named Tuples for Readable Records

Positions like r[1] are hard to read. collections.namedtuple creates a tuple type whose fields also have names:

from collections import namedtuple

Course = namedtuple("Course", ["code", "units", "grade"])
c = Course("PHY101", 3, "A")
print(c.code, c.units, c[2])
print(c)
code, units, grade = c          # still unpacks like a tuple
c2 = c._replace(grade="B")      # returns a new tuple
print(c2.grade, c.grade)

Output:

PHY101 3 A
Course(code='PHY101', units=3, grade='A')
B A

The modern alternative typing.NamedTuple uses class syntax with type hints and works the same way. For records that need to change, use a dataclass instead.

Tuples or Lists?

  • Use a list for a collection of similar items that may grow, shrink or be sorted in place, such as a list of student names.
  • Use a tuple for a fixed group of related values, often of different types, such as a coordinate, an RGB colour or a database row.
  • Tuples protect data from accidental changes and can be dictionary keys.
  • Tuples are slightly smaller in memory and faster to create than lists, though the difference rarely matters.

Summary

  • Python tuples are ordered, immutable sequences; the comma creates them, and one-item tuples need a trailing comma.
  • They support indexing, slicing, in, count and index, but no methods that change them.
  • Packing and unpacking allow swaps, multiple return values and clean loops; *rest collects leftovers.
  • Hashable tuples can be dictionary keys and set members.
  • Named tuples give fields readable names while keeping tuple behaviour.

Related Tutorials