Looping over multiple iterables at once

Series: Looping
Trey Hunner smiling in a t-shirt against a yellow wall
Trey Hunner
3 minute read Python 3.7—3.10
Share
Python Morsels
Watch as video
02:40

Often we have to loop over two iterables at the same time.

Looping over multiple iterables

An iterable in Python is anything you're able to loop over with a for loop. Lists are the type of iterable that we are using here.

We have two list here fruits and colors, we want to loop over them at the same time to get color for each fruit:

>>> fruits = ["loquat", "jujube", "pear", "watermelon", "apple"]
>>> colors = ["brown", "orange", "green", "pink", "purple"]

We are looping over the fruits here:

>>> fruits = ["loquat", "jujube", "pear", "watermelon", "apple"]
>>> colors = ["brown", "orange", "green", "pink", "purple"]
>>>
>>> for fruit in favorite_fruits:
...     print(fruit)
...
loquat
jujube
pear
watermelon
apple

Using nested for loops

If we will to put another for loop inside it, this wouldn't actually do what we want here:

>>> fruits = ["loquat", "jujube", "pear", "watermelon", "apple"]
>>> colors = ["brown", "orange", "green", "pink", "purple"]
>>>
>>> for fruit in fruits:
...     for color in colors:
...         print(color, fruit)
...
brown loquat
orange loquat
green loquat
pink loquat
purple loquat
brown jujube
orange jujube
green jujube
pink jujube
purple jujube
brown pear
orange pear
green pear
pink pear
purple pear
brown watermelon
orange watermelon
green watermelon
pink watermelon
purple watermelon
brown apple
orange apple
green apple
pink apple
purple apple

We instead want brown loquat because these two correspond to each other up here, they're in the same position. We also want orange jujube, green pear and so on. We don't want green loquat, for example.

We want only the things that correspond to each other so we can't use a nested loop.

We somehow need to loop over fruits at the same time as colors.

Indexing with enumerate

We could grab and use an index to get the result here. We can use a number n counting upward as we loop and use enumerate to count upward as we loop over our fruits iterable:

>>> fruits = ["loquat", "jujube", "pear", "watermelon", "apple"]
>>> colors = ["brown", "orange", "green", "pink", "purple"]
>>>
>>> for n, fruit in enumerate(fruits):
...     print(n, fruit)
...
0 loquat
1 jujube
2 pear
3 watermelon
4 apple

We can then use that number n as an index inside of colors. This will give us the corresponding values.

>>> fruits = ["loquat", "jujube", "pear", "watermelon", "apple"]
>>> colors = ["brown", "orange", "green", "pink", "purple"]
>>>
>>> for n, fruit in enumerate(fruits):
...     print(colors[n], fruit)
...
brown loquat
orange jujube
green pear
pink watermelon
purple apple

This works only for sequences because it can be indexed starting from 0. For non-sequences, like a generator, a file, a set, a dictionary, lots of iterables in Python that are not sequences, this is not going to work. We can't index non-sequences.

Using the built-in zip function

There's another built-in function that is called zip, you can give it any number of iterables:

>>> colors = ["brown", "orange", "green", "pink", "purple"]
>>> fruits = ["loquat", "jujube", "pear", "watermelon", "apple"]
>>>
>>> for item in zip(fruits, colors):
...     print(item)
...
('loquat', 'brown')
('jujube', 'orange')
('pear', 'green')
('watermelon', 'pink')
('apple', 'purple')

The return value of zip is a tuple of each of the items in colors and fruits, that are in corresponding positions. The first one from each (loquat, brown), the second one from each (jujube, orange), and so on, and it will stop at the shortest one.

We can use tuple unpacking here and do whatever we'd like with these variables, fruits and colours here:

>>> fruits = ["loquat", "jujube", "pear", "watermelon", "apple"]
>>> colors = ["brown", "orange", "green", "pink", "purple"]
>>>
>>> for fruit, color in zip(fruits, colors):
...     print(color, fruit)
...
brown loquat
orange jujube
green pear
pink watermelon
purple apple

Summary

If you need to loop over multiple iterables at the same time, the best way to do that in Python is with the built-in zip function.

Series: Looping

Unlike, JavaScript, C, Java, and many other programming languages we don't have traditional C-style for loops. Our for loops in Python don't have indexes.

This small distinction makes for some big differences in the way we loop in Python.

To track your progress on this Python Morsels topic trail, sign in or sign up.

0%
Write more Pythonic code

Need to fill-in gaps in your Python skills? I send regular emails designed to do just that.