Skip to content

#310: The Zip() Function

Last week we explored the most useful functions of the itertools module to cover some of the most common use-cases we have with lists. However, there is one case we left open for this post: combining multiple iterables that are related into a single iterable. In this post we explore how the zip() function allows us to do that.

What does zip()?

At its core, zip() takes two or more iterables and aggregates them element by element. The result is an iterator of tuples, where each tuple contains one element from each of the input iterables. If the input iterables are of different lengths, zip() stops at the shortest iterable.

The syntax is straightforward:

zip(iterable1, iterable2, ...)

A minimal example

We have two list, one with names and the other one with ages. If we want to pair each name with its corresponding age, we can use the zip() function like this:

1
2
3
4
5
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]

combined = zip(names, ages)
print(list(combined))
[('Alice', 25), ('Bob', 30), ('Charlie', 35)]

In this example, zip() pairs the first element of names with the first element of ages, the second element with the second, and so on. Converting the result to a list makes it easier to visualise.

Using zip() with loops

One of the most common uses of zip() is in loops. Instead of using indices to access elements of multiple lists, we can loop directly through the paired elements:

for name, age in zip(names, ages):
    print(f"{name} is {age} years old")
Output:
Alice is 25 years old
Bob is 30 years old
Charlie is 35 years old

This approach is cleaner and less error-prone than manually handling list indices.

Working with multiple lists

We can use the zip() function with more than two lists. The principle of combining elements from each iterable stays the same, only our tuples get bigger:

1
2
3
4
5
6
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
cities = ["New York", "London", "Tokyo"]

combined = zip(names, ages, cities)
print(list(combined))
[('Alice', 25, 'New York'), ('Bob', 30, 'London'), ('Charlie', 35, 'Tokyo')]

Working with lists of different length

If we have two lists but they differ in length, zip() stops when the shorter list runs out of elements:

1
2
3
4
5
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30]

combined = zip(names, ages)
print(list(combined))
[('Alice', 25), ('Bob', 30)]

If we want to get all elements and fill the missing values with None, we can use the zip_longest() function from the itertools module:

1
2
3
4
5
6
7
from itertools import zip_longest

names = ["Alice", "Bob", "Charlie"]
ages = [25, 30]

combined = zip_longest(names, ages, fillvalue=None)
print(list(combined))
[('Alice', 25), ('Bob', 30), ('Charlie', None)]

Conclusion

If we have lists that contain related data, the zip() function can help us to combine the values into a tuple. That way we can focus on the result and save ourselves the extra code to access the different lists by index. It only looks like a small improvement, but such shortcuts add up.