Skip to content
FollowtheDamnCode

enumerate and zip

Positions and parallel lists, without range(len(...)).

4 minute read

Big idea

enumerate gives you each item and its position; zip walks through several sequences side by side. Together they replace almost every for i in range(len(...)) loop.

enumerate

The clumsy way to number a list:

for i in range(len(names)):
    print(i + 1, names[i])

The Python way:

Numbered with enumerate
names = ["Ada", "Grace", "Linus"]
for i, name in enumerate(names, start=1):
    print(f"{i}. {name}")
output
1. Ada
2. Grace
3. Linus

Run and edit it in the app.

enumerate produces (index, item) pairs, which the loop unpacks into i and name. start=1 counts from 1 instead of 0.

zip

Predict: two lists in step
names = ["Ada", "Grace", "Linus"]
scores = [88, 95, 72]
for name, score in zip(names, scores):
    print(name, score)
print(dict(zip(names, scores)))
What does it print? Show the answer
Ada 88
Grace 95
Linus 72
{'Ada': 88, 'Grace': 95, 'Linus': 72}

Run and edit it in the app.

zip pairs the first items, then the second items, and so on. dict(zip(keys, values)) is a classic way to build a dictionary from two lists.

zip pairs items by position

Watch it

Uneven lengths

zip stops at the shortest sequence — extra items are silently dropped:

Fix the bug: zip should refuse lists of different lengths
days = ["Mon", "Tue", "Wed"]
temps = [21, 23]
try:
    for day, t in zip(days, temps):
        print(day, t)
except ValueError:
    print("Lengths don't match!")
output
Mon 21
Tue 23
Lengths don't match!

Run and edit it in the app.

Since Python 3.10, zip(days, temps, strict=True) raises a ValueError when the lengths differ — so a missing reading can't go unnoticed.

Both together

Position, name, and score
names = ["Ada", "Grace"]
scores = [88, 95]
for rank, (name, score) in enumerate(zip(names, scores), start=1):
    print(rank, name, score)
output
1 Ada 88
2 Grace 95

Run and edit it in the app.

Note the brackets: each item of enumerate is (rank, (name, score)), so the loop unpacks it the same shape.

What does list(enumerate("ab")) give?

Think of it like

enumerate is a ticket machine at a deli counter — every customer gets a number. zip is a zip on a jacket: two rows of teeth joined pair by pair, stopping where the shorter side ends.

Key terms

  • enumerate — Gives (index, item) pairs.
  • zip — Combines sequences into tuples, position by position.
  • strict=True — Makes zip raise an error if the lengths differ.

Check yourself

What does enumerate(items, start=1) give on each round?

What does list(zip([1, 2, 3], 'ab')) give?

How do you build a dict from a list of keys and a list of values?