Q&A library Python

How do I loop over two lists at once in Python?

Python Beginner iterationloopszip

Short answer

Use zip to pair the items from two sequences and loop over the pairs. Note that zip stops at the shorter one, silently ignoring extra items, so pass strict=True to catch a length mismatch.

The short version

Use zip to walk two (or more) sequences together, pairing their items. Be aware that zip stops at the shortest one and silently discards the extras. On Python 3.10 and later, pass strict=True so a length mismatch raises instead of being ignored.

Pairing two sequences

names = ["pen", "mug", "cup"]
prices = [2, 5, 4]

for name, price in zip(names, prices):
    print(name, price)

Each iteration yields a tuple, which the two names on the left unpack. It is far clearer than indexing both lists with a shared counter.

The pattern it replaces

for i in range(len(names)):
    print(names[i], prices[i])   # clumsy, and breaks if the lists differ in length

This is harder to read and assumes the lists are the same length without checking.

The silent truncation trap

list(zip([1, 2, 3], ["a"]))   # [(1, 'a')] , items 2 and 3 vanish

zip stops when the shortest sequence runs out, with no warning. If the two lists were supposed to correspond one to one, a mismatch means your data is wrong, and silently dropping the extras hides that.

The fix: strict=True

list(zip([1, 2, 3], ["a"], strict=True))
# ValueError: zip() argument 2 is shorter than argument 1

This turns a silent data loss into a clear error. Use it whenever the sequences are meant to be the same length, which is nearly always. It was added in Python 3.10.

Zipping more than two

zip takes any number of sequences.

for name, price, stock in zip(names, prices, stocks, strict=True):
    ...

Building a dictionary

A very common use is pairing keys with values.

dict(zip(names, prices))   # {'pen': 2, 'mug': 5, 'cup': 4}

Unzipping

The star operator reverses it, splitting a list of pairs back into separate sequences.

pairs = [("pen", 2), ("mug", 5)]
names, prices = zip(*pairs)

With an index too

Combine with enumerate when you need the position as well.

for i, (name, price) in enumerate(zip(names, prices, strict=True), start=1):
    print(i, name, price)

Note the brackets around (name, price), which unpack the inner tuple that zip produced.

Need this solved on your own data?

The library is free and always will be. When the problem is bigger than an answer, we take on the work.

Start a project