What Does the Zip() Function Do in Python? Let’s Discover It

If you haven’t used the Python zip() function yet this is an opportunity to look at how it works and how you can use it in your programs.

The Python zip() function takes as input multiple iterables and returns an iterator of tuples where the n-th tuple contains the n-th element from every iterable. The zip function can also be applied to iterable of different length and in that case it stops when the smallest iterable is exhausted.

We will go through some example to see how to apply the zip function to multiple Python data types.

Let’s zip them all!

Python Zip Function Applied to Two Lists

The Python zip() function aggregates items from multiple iterables and returns an iterator of tuples.

zip(*iterables)

It can be a bit abstract if just explained this way, let’s see how it works in practice when applied to two lists.

>>> cities = ['Warsaw', 'Rome', 'Prague']
>>> countries = ['Poland', 'Italy', 'Czech Republic']
>>> zip(cities, countries)
<zip object at 0x7f94081e9240>

As mentioned before the zip object returned is an iterator of tuples, let’s see if we can iterate through it…

>>> for value in zip(cities, countries):
...     print(value)
... 
('Warsaw', 'Poland')
('Rome', 'Italy')
('Prague', 'Czech Republic')

As you can see each item returned by the iterator object is a tuple where the first element comes from the first list and the second element comes from the second list.

The result is the same when Python zip is applied to three lists or more.

You can also use the following approach with a for loop:

>>> for city, country in zip(cities, countries):
...     print(city, country)
... 
Warsaw Poland
Rome Italy
Prague Czech Republic

It allows to refer to each item in every tuple directly without having to access the elements of each tuple by index.

Python Zip Function Applied to Lists of Different Length

Now, let’s see another example of how to use the zip function.

What happens if we remove one element from the second list?

>>> cities = ['Warsaw', 'Rome', 'Prague']
>>> countries = ['Poland', 'Italy']
>>> for value in zip(cities, countries):
...     print(value)
... 
('Warsaw', 'Poland')
('Rome', 'Italy')

When two lists of different size are passed to the zip function the iterator of tuples returned stops when the shortest list is exhausted.

Zip Function Applied to a Single List

Considering that the zip() function puts together elements coming from multiple iterables I wonder what happens if we only pass one list to it.

>>> cities = ['Warsaw', 'Rome', 'Prague']
>>> for value in zip(cities):
...     print(value)
... 
('Warsaw',)
('Rome',)
('Prague',)

If a single list (or iterable) is passed to the Python zip function it returns an iterator of 1-tuples (tuples with a single element).

Can You Use the Zip Function With Different Data Types?

We have seen how to use zip() with two lists…

…but I wonder if we can pass different data types to the zip function.

For example, let’s say we have two tuples (the tuple is an iterable) and one list.

>>> cities = ('Warsaw', 'Rome', 'Prague')
>>> countries = ('Poland', 'Italy', 'Czech Republic')
>>> languages = ['Polish', 'Italian', 'Czech']
>>> list(zip(cities, countries, languages))
[('Warsaw', 'Poland', 'Polish'), ('Rome', 'Italy', 'Italian'), ('Prague', 'Czech Republic', 'Czech')]

The result of the zip function is exactly the same, an iterator of tuples.

The first tuple returned contains the first item from the first tuple, the first item from the second tuple and the first item from the list.

And the same applies to the second and third tuple.

Also notice that this time we have used the list() built-in function to convert the iterator into a list.

The conversion to a list is required to see the tuples returned by the iterator considering that if you try to print the object returned by the zip function you won’t be able to see much (just a zip object):

>>> print(zip(cities, countries, languages))
<zip object at 0x7fe4e02e9740>

How to Zip Two Lists of Lists

Let’s make things a bit more complex…

…I want to see what happens when we try to zip two lists of lists.

What do you think?

>>> numbers_group1 = [[1, 2], [3, 4], [5, 6]]
>>> numbers_group2 = [[7, 8], [9, 10], [11, 12]]
>>> list(zip(numbers_group1, numbers_group2))
[([1, 2], [7, 8]), ([3, 4], [9, 10]), ([5, 6], [11, 12])]

The principle is the same, the iterator returned by the zip function is an iterator of tuples.

When you apply the zip() function to two lists of lists the result is an iterator of tuples where every tuple has two elements and each element in a given tuple is a list.

If you want to access, for example, the first number of the first list in the first tuple you can use the following syntax.

>>> list(zip(numbers_group1, numbers_group2))[0][0][0]
1

Using the Zip Function with Two Strings

Python strings are iterables and hence they can be passed to the zip() function.

Define two strings and pass them to the zip function.

>>> value1 = "hello"
>>> value2 = "Codefather"
>>> for value in zip(value1, value2):
...     print(value)
... 
('h', 'C')
('e', 'o')
('l', 'd')
('l', 'e')
('o', 'f')

The zip function when applied to two strings returns an iterator of tuples where every tuple contains one character from each string.

As we have seen before the iterator stops at the shortest string between the two.

And now…

…let’s say you want to merge the output of the zip function into a single string.

How would you do it?

Hint: you can use the string join() function.

Let’s start from here, we want to create a single string “hCeoldleof”.

>>> list(zip(value1, value2))
[('h', 'C'), ('e', 'o'), ('l', 'd'), ('l', 'e'), ('o', 'f')]

First of all we can join the characters of each tuple with a generator expression.

>>> (''.join(x) for x in zip(value1, value2))
<generator object <genexpr> at 0x7f93f80913c0>
>>> list(''.join(x) for x in zip(value1, value2))
['hC', 'eo', 'ld', 'le', 'of']

And then we can apply the join() function again to merge every element into a single string.

>>> ''.join(''.join(x) for x in zip(value1, value2))
'hCeoldleof'

Mission accomplished!! 😀

Using the Zip Function with Python Sets

Python sets are iterable objects and for this reason the zip() function can be applied to them.

Let’s see what happens when we pass the following two sets to the zip function.

>>> cities = {'Warsaw', 'Rome', 'Prague'}
>>> countries = {'Poland', 'Italy', 'Czech Republic'}

Here is the output of the zip function casted to a list.

>>> print(zip(cities, countries))
<zip object at 0x7f94081e9300>
>>> print(list(zip(cities, countries)))
[('Warsaw', 'Poland'), ('Prague', 'Italy'), ('Rome', 'Czech Republic')]

So, once again we get back a list of tuples from the iterator. Each tuple contains one item from the first set and one item from the second set.

Also…

I want to show you another way to see the tuples returned by the iterator.

>>> merged_sets = zip(cities, countries)
>>> next(merged_sets)
('Warsaw', 'Poland')
>>> next(merged_sets)
('Prague', 'Italy')
>>> next(merged_sets)
('Rome', 'Czech Republic')
>>> next(merged_sets)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

To go trough the iterator we have used the Python next() function.

How to Zip Two Lists into a Dictionary

The zip function in Python can be used together with the dict() function to create a dictionary starting from two lists.

As we have seen before this is what you get back if you convert the iterator returned by the zip function into a list.

>>> attributes = ['country', 'capital', 'language']
>>> values = ['Poland', 'Warsaw', 'Polish']
>>> print(list(zip(attributes, values)))
[('country', 'Poland'), ('capital', 'Warsaw'), ('language', 'Polish')]

To create a dictionary instead of using the list() function we can apply the dict() function to the iterator returned by the zip function.

>>> print(dict(zip(attributes, values)))
{'country': 'Poland', 'capital': 'Warsaw', 'language': 'Polish'}

That’s pretty cool!

A little trick to remember when you want to create a dictionary from existing keys and values.

Conclusion

Python’s zip function is quite interesting and it allows you to perform operations with iterables that otherwise would require custom code.

How are you planning to use the zip function in your code?

Leave a Comment