Step 1 of 8 · Reading · ~4 min
Learn
Lists and Tuples
Tuples and Unpacking
By the end of this lesson you can build fixed records, take them apart in one assignment, and sort records so that ties fall to the next field.
In Python Fundamentals, enumerate and zip handed you pairs such as (1, "red"). A pair like that is a tuple: an ordered, fixed group of values. A string cannot change once built; a tuple is the same idea for a mixed record.
Making a tuple
The comma makes the tuple, not the parentheses. Indexing and slicing work as on strings and lists.
<class 'int'> <class 'tuple'>
Assigning into a tuple fails: a[0] = 2000 raises TypeError: 'tuple' object does not support item assignment. The limit of that rule is that the tuple fixes which objects it holds, not what they contain:
Unpacking
Unpacking assigns each item of a tuple to its own name. The number of names must match the number of items:
The last line fails: ValueError: not enough values to unpack (expected 3, got 2).
A starred name collects whatever is left, always as a list. _ is the usual name for a value you do not need:
Star-unpacking still needs the fixed names filled: first, *middle, last = [7] raises ValueError: not enough values to unpack (expected at least 2, got 1).
Unpacking nests. Each pair from enumerate is a tuple, and when that tuple holds another tuple, the header mirrors its shape:
1 Zed 1999
2 Mia 1984
Drop the inner parentheses and enumerate yields two things for three names: ValueError: not enough values to unpack (expected 3, got 2).
Tuples compare field by field
Python compares two tuples at the first position, and moves to the next only if they are equal. So sorting records sorts by their first field, then the second, and so on:
[(1984, 'Mia'), (1999, 'Ada'), (1999, 'Zed')]
(1984, 'Mia') (1999, 'Zed')
The two 1999 records tie on year, so "Ada" beats "Zed" no matter which came first. The order of fields is therefore a decision: ("Zed", 1999) would sort by title first. Types matter as well: (9, 1) sorts before (10, 2), but ("9", 1) sorts after ("10", 2), because text compares character by character.
namedtuple: fields with names
point[0] says nothing about what it holds. namedtuple from the standard library builds a tuple type whose fields have names:
from collections import namedtuple loads one name from a module of the standard library, so it can be used without the collections. prefix. Setting b.year = 2000 raises AttributeError; it is still a tuple.
Common mistakes
- Fields in the wrong order. Sorting
(name, time)tuples ranks alphabetically, so the fastest runner is not first. Put the field you rank by first. - Comparing text instead of numbers. Without
int(...),"9500"sorts after"10000", so the slowest entry is wrong. - Too few parentheses.
for place, ms, name in enumerate(...)crashes withexpected 3, got 2; the pair needs its own parentheses. - Starring a short sequence.
first, *middle, last = itemsfails whenitemshas one element.
Your exercise
Rank race entries from fastest to slowest and print the podium, the slowest entry and the gap. The starter already reads each entry as a (name, ms) pair; the ranking must come from the tuples themselves, so times that tie are listed alphabetically.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…