Computer Science

# Coiteration with zip

There are times when we want to iterate over two lists at the same time. For example, we may have a list of fruits:

fruits = ['apple', 'pear', 'peach']

and a list of prices:

prices = [0.25, 0.40, 10.0]

and we want to print a list that shows each fruit and its price:

apple : \$0.25
pear : \$0.40
peach : \$10.0

Yes, peaches are worth that much more than any other fruit. They are amazing.

## zip

To iterate over two lists at the same time, we can use zip() to turn combine the two lists. This code is in fruit_prices.py:

if __name__ == '__main__':
fruits = ['apple', 'pear', 'peach']
prices = [0.25, 0.40, 10.0]
for fruit, price in zip(fruits, prices):
print(f'{fruit} : \${price}')

This will produce the list of fruits and their prices as shown above.

How is this working? The zip() function creates a collection of tuples:

(apple, 0.25)
(pear, 0.40)
(peach, 10.0)

You can then iterate over this collection using for ... in, just like with a list, a file, or a string.

## You can zip as many lists as you want

You don’t have to stop at zipping just two lists. Here is an example that zips three lists, which you can find in students.py:

if __name__ == '__main__':
names = ['John', 'Juan', 'João', 'Giovanni']
ages = [23, 18, 24, 22]
majors = ['Chemistry', 'Animation', 'Sociology', 'Secondary Education']

for name, age, major in zip(names, ages, majors):
print(f'{name} is {age} years old and studies {major}')

## zip stops zipping as soon as one of the lists runs out

Thsi code is in unequal_lists.py. If you zip these lists:

if __name__ == '__main__':
fruits = ['apple', 'pear', 'blueberry', 'grape', 'strawberry']
plant_types = ['tree', 'tree', 'bush', 'vine']

for fruit, plant_type in zip(fruits, plant_types):
print(f'The {fruit} grows on a {plant_type}.')

Then you get this output:

The apple grows on a tree.
The pear grows on a tree.
The blueberry grows on a bush.
The grape grows on a vine.

Notice that we never get any output about strawberry because there is no accompanying plant type for this fruit.

## zip works with anything that is iterable

Since zip() works with anything that is iterable, you can use it to zip strings as well. This code is in compare_strings.py:

if __name__ == '__main__':
word1 = 'planter'
word2 = 'started'

for letter1, letter2 in zip(word1, word2):
if letter1 == letter2:
print(f'{letter1} == {letter2} ✅')
else:
print(f'{letter1} != {letter2}')

This will print:

p != s
l != t
a == a ✅
n != r
t == t ✅
e == e ✅
r != d

## enumerate

Sometimes you want to iterate through a list and get the index for each item as you go. You can get the indexes for a list with enumerate(). See this code in names.py:

if __name__ == '__main__':
for index, name in enumerate(['Paula', 'Patty', 'Peter', 'Penelope']):
print(f'{index}: {name}')

This will print:

0: Paula
1: Patty
2: Peter
3: Penelope

It turns out that enumerate() returns a collection of tuples, just like zip().