DataLens

Tuples and when to use them

Fixed, unchangeable groups of values: how tuples differ from lists, unpacking, and why immutability is a feature.

Level: Foundations · 9 min read

Practise this module

The questions for this lesson run in your browser and check your answer straight away.

The idea

A tuple is like a list that can't be changed. It's an ordered group of values, written with round brackets:

location = (-6.2088, 106.8456)     # latitude, longitude of Jakarta
order = ("NG-24107", "2024-09-15", 798000)
print(location[0])
print(order[-1])
print(len(order))
-6.2088
798000
3

Indexing, negative indexes, slicing and len() all work exactly as with lists. What you can't do is change a tuple once it exists:

order[2] = 800000
TypeError: 'tuple' object does not support item assignment

So why would you want a list that's missing features? Because "this can't change" is a promise, and promises make code easier to trust.

Analogy

A list is a shopping list on a whiteboard: you keep adding and crossing off. A tuple is a printed receipt: it records exactly what happened, and nobody should edit it afterwards.

Lists versus tuples

The rule of thumb used by experienced Python programmers:

In a list, every item plays the same role. In a tuple, position 0 might be a name, position 1 a city and position 2 an amount. That's why tuples are often described as "lightweight records".

ListTuple
Syntax[1, 2, 3](1, 2, 3)
Can change?Yes (mutable)No (immutable)
Typical usemany items of one kindone record of a few fields
Methodsmany (append, sort…)just count and index

Creating tuples

The brackets are actually optional. It's the commas that make a tuple:

point = 3, 4
print(type(point))
single = ("Jakarta",)
not_a_tuple = ("Jakarta")
print(type(single), type(not_a_tuple))
<class 'tuple'>
<class 'tuple'> <class 'str'>

A one-item tuple needs a trailing comma: ("Jakarta",). Without it, the brackets are just ordinary grouping brackets and you get a plain string. You'll rarely need a one-item tuple, but now you won't be confused when you see one.

You can turn a list into a tuple with tuple(), and back with list():

cities = ["Jakarta", "Bandung"]
frozen = tuple(cities)
print(frozen)
print(list(frozen))
('Jakarta', 'Bandung')
['Jakarta', 'Bandung']

Unpacking: the real superpower

Unpacking assigns each item of a tuple to its own variable in one line. You already used it for swapping in the variables module; now you can see what was happening:

order = ("NG-24107", "2024-09-15", 798000)
order_id, date, total = order
print(order_id)
print(total)
NG-24107
798000

The number of names on the left must match the number of items. Unpacking turns order[2] (what was index 2 again?) into total, which explains itself.

If you only need some of the values, the convention is to use _ for the ones you're ignoring, and * to collect "the rest" into a list:

order_id, _, total = order
print(order_id, total)

first, *others = ["Ayu", "Budi", "Citra", "Dimas"]
print(first)
print(others)
NG-24107 798000
Ayu
['Budi', 'Citra', 'Dimas']

Returning several values

Tuples appear whenever a piece of code hands back more than one value. Python's built-in divmod() returns the floor division and the remainder together, as a tuple:

result = divmod(135, 60)
print(result)
hours, minutes = divmod(135, 60)
print(f"{hours} h {minutes} min")
(2, 15)
2 h 15 min

When you write your own functions in a later module, you'll return tuples the same way, and the caller will unpack them.

Tuples as dictionary keys and set members

Because tuples can't change, Python can use them in places where lists aren't allowed, such as dictionary keys and set items (both coming up next). For example, a dictionary of delivery fees keyed by (from_city, to_city) pairs is natural with tuples and impossible with lists.

route = ("Jakarta", "Bandung")
print(hash(route) == hash(("Jakarta", "Bandung")))
True

The technical word is hashable: Python can compute a fixed fingerprint (a hash) for the value because it never changes. Lists are not hashable, since their contents could change after the fingerprint was taken.

Watch out

A tuple is only as frozen as its contents. A tuple containing a list, like (1, [2, 3]), can't have its items reassigned, but the list inside can still be changed. Keep tuples made of simple values (numbers, strings, other tuples) and they behave as you'd expect.

Why this matters for clean code

Choosing a tuple tells the next reader "this group of values belongs together and won't change". That's information they don't have to work out. Combined with unpacking (order_id, date, total = order), tuples let you give every value a meaningful name at the moment you use it, instead of scattering mystery indexes like row[2] through your code.

Recap

Practise this module

The questions for this lesson run in your browser and check your answer straight away.