enumerate and zip

Introduction

Two built-in functions make loops over lists cleaner: enumerate adds a counter, and zip pairs up items from several lists.

Index arithmetic such as names[i] and marks[i] is a common source of small mistakes. These two functions let the loop hand you exactly what you need, which is both shorter and safer.

How it works

A counter with enumerate

names = ["Rahim", "Nadia", "Karim"]
for position, name in enumerate(names, start=1):
    print(position, name)
Open in compiler

enumerate(names, start=1) gives pairs: (1, 'Rahim'), (2, 'Nadia'), (3, 'Karim'). The loop unpacks each pair into position and name. Without start=1 the count begins at 0.

The older way

names = ["Rahim", "Nadia"]
for i in range(len(names)):
    print(i, names[i])
Open in compiler

for i in range(len(names)) with names[i] works, but it is longer and easier to get wrong. Prefer enumerate when you need the position, and plain for name in names when you do not.

Syntax

for i, name in enumerate(names, start=1):
    print(i, name)
for name, mark in zip(names, marks):
    print(name, mark)

Example

names = ["Rahim", "Nadia", "Karim"]
marks = [72, 91, 85]
for name, mark in zip(names, marks):
    print(name, mark)
best = max(zip(marks, names))
print("Top:", best[1])
Open in compiler

zip(names, marks) pairs the first name with the first mark, the second with the second, and so on. max(zip(marks, names)) compares the pairs by mark first, so it finds the top student: Nadia, with 91.

Line by line

  1. names and marks are two lists in matching order.
  2. zip(names, marks) makes pairs, and the for line unpacks each one.
  3. Each pass prints one name and its mark.
  4. max(zip(marks, names)) compares the pairs by mark first and finds the largest.
  5. best[1] is the name part of that pair.

Expected result

Rahim 72
Nadia 91
Karim 85
Top: Nadia

In the real world

Data often arrives as matching columns, such as dates and prices, and zip joins them back up. Numbered lists and menus are the everyday use of enumerate.

Common mistakes

  • Lists of different lengths: zip stops at the shortest one and silently drops the rest.
  • Forgetting to unpack: for pair in enumerate(names) gives tuples like (0, 'Rahim').
  • Expecting zip(...) to print as a list: it is lazy; use list(zip(...)) to see it.

Best practices

  • Use for x in items when you do not need the position.
  • Use enumerate when you need the position, and zip for parallel lists.
  • Check that lists have the same length before relying on zip.

Summary

enumerate adds a counter to a loop, and zip pairs up several lists and stops at the shortest. Unpacking in the for line gives each part a name.

Practice

Given names and marks, print a numbered list like 1. Rahim: 72 using enumerate and zip together.

Quick check

1. What is the first pair from enumerate(['a', 'b'])?
2. What does list(zip([1, 2, 3], ['x', 'y'])) give?
3. Which loop gives both the position and the item?

Key takeaways

  • enumerate gives you the position without any index arithmetic.
  • zip stops at the shortest list.
  • Unpacking keeps a loop short and clear.

Practice problems for this lesson

My notes

Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.