5 Important Facts About Tuples in Python

Tuples in Python

Tuples in Python are one of the language’s core sequence types, prized for being ordered yet unchangeable once created.

A tuple is a sequence of values, written inside parentheses and separated by commas, that looks almost identical to a list in every way except one: once created, a tuple cannot be changed. No element can be added, removed, or reassigned. That single restriction – immutability – is the entire reason tuples exist as a separate type rather than Python simply making do with lists alone.

Creating a Tuple

point = (4, 7)
colors = ('red', 'green', 'blue')
print(point)
print(colors)

A one-element tuple needs a trailing comma to be recognized as a tuple at all – (5) is just the number 5 in parentheses, while (5,) is a one-item tuple. This trips up nearly everyone the first time they hit it.

Why Immutability Matters

Trying to change an element of a tuple after creating it raises an error immediately, rather than letting the mistake pass silently:

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

This isn’t a limitation so much as a deliberate guarantee. When you pass a tuple into a function, or store one as a dictionary key, or hand a reference to it to another part of a large program, you know with certainty that nothing downstream can quietly modify it behind your back. Lists offer no such guarantee – and in fact, that guarantee is precisely why only immutable types like tuples, strings, and numbers are allowed as dictionary keys; a list can never be used as one, because Python needs to know a key’s value will never shift after it’s been used to file something away. Immutability also lets Python store tuples slightly more efficiently in memory and access their elements a bit faster than the equivalent list, since the interpreter never has to account for the tuple’s size or contents changing later.

In practice, this makes tuples the natural choice for data that represents a fixed, related group of values – a coordinate pair, an RGB color, a date – while lists remain the better choice for collections you expect to grow, shrink, or rearrange over the life of the program.

Accessing Elements

Indexing and slicing work exactly as they do with lists and strings – tuples support reading by position, they just don’t support writing.

colors = ('red', 'green', 'blue', 'yellow')
print(colors[0])       # red
print(colors[-1])      # yellow
print(colors[1:3])     # ('green', 'blue')
print(len(colors))     # 4

Unpacking a Tuple

One of the most useful things about tuples is how naturally they unpack into separate variables in a single line.

point = (4, 7)
x, y = point
print(x)   # 4
print(y)   # 7

This is also exactly how Python lets you swap two variables in a single line without a temporary holding variable, something most other languages can’t do so directly:

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

Behind the scenes, Python builds the tuple (b, a) on the right side first, fully evaluated, and only then unpacks it into a and b on the left – which is why there’s never a moment where the swap could read a half-updated value.

When you only want some of the values and want to collect the rest together, the * operator can grab “everything else” as a list during unpacking:

scores = (91, 85, 78, 62, 99)
highest, *rest = scores
print(highest)   # 91
print(rest)      # [85, 78, 62, 99]

Returning Multiple Values from a Function

Tuples are also the mechanism behind a feature that looks, at first glance, like a function returning more than one value at once.

def min_max(numbers):
    return min(numbers), max(numbers)

low, high = min_max([4, 9, 1, 7])
print(low, high)   # 1 9

A function can only ever return one object, but return min(numbers), max(numbers) is really returning a single two-item tuple, which the caller then unpacks into low and high on the way out. It looks like multiple return values because tuple creation and tuple unpacking are both so lightweight in Python that the two together read almost like a language feature of their own.

namedtuple: Tuples with Labeled Fields

Plain tuples are accessed by position, which means point[0] and point[1] work but don’t say anything about what those positions actually mean. The namedtuple helper, part of Python’s built-in collections module, creates a tuple subclass whose fields can also be accessed by name, while remaining exactly as immutable and lightweight as an ordinary tuple.

from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])
p = Point(4, 7)

print(p.x, p.y)   # 4 7
print(p[0], p[1]) # 4 7   (still works by index too)

Use a plain tuple when the meaning of each position is obvious from context; reach for namedtuple once a tuple starts carrying enough fields that p[0] and p[1] stop being self-explanatory to whoever reads the code next.

For the mutable counterpart to everything covered here, see Lists in Python.

No Comments

Leave a Reply

Recent Comments

No comments to show.