Python Zip Function: A Comprehensive Guide

The python zip function is a built-in python function that merges the elements of an iterator object to another iterable object and returns a tuple object. In other words, the zip function in python maps the elements of two or more iterables based on its index and returns its aggregation. If you don’t know what an iterable is, an iterable is an object in python that can be looped over and returns each element one at a time. Examples of iterable are lists, tuples, dictionaries, strings, etc. 

In this tutorial, you will learn about the python zip function and how to use it effectively. Let’s begin with its syntax according to the official Python documentation

Zip Function Syntax

Docstring:     
zip(iter1 [,iter2 [...]]) --> zip object

Return a zip object whose .__next__() method returns a tuple where
the i-th element comes from the i-th iterable argument.  The .__next__()
method continues until the shortest iterable in the argument sequence
is exhausted and then it raises StopIteration.
Type:           type

The definition looks like a handful but in the course of this tutorial, you will understand it better. There will be coding examples to solidify your understanding of the zip function and know how to apply the function to solve real-world problems. 

Using Zip() in Python

Upon calling the zip() function, the iterables are merged and an object that aggregates the elements of the individual iterables with the same index is returned. It does this until the function has run out of iterable objects where it raises the StopIteration exception and terminates. Note that the zip function takes parameters that are iterables or collections only.

The arguments passed to the python zip() function are typically two or more iterables of the same length. There are special cases to how the zip() function works, however. Such cases include when the zip() function has only one argument (1 iterable object) passed, or in some cases, no argument passed at all. There could also be situations where the length of the individual iterables are not the same. Momentarily, we will discuss each of these special cases and see how the zip function handles them. 

Let’s get started with the use cases highlighted above. 

Passing Two Parameters on the Python Zip Function

Imagine you have two separate lists, one containing the names of employees and the other their ages. If you wish to merge the two lists into one with each name with his corresponding age, you can do so using the zip function in python. This is perhaps the most common use case of the zip function. See an example in the code shown below. 

#The python code below demostrates the use of the zip() function for two iterables

#define the list of employees names and their age
employee_names = ['Vash', 'Ben', 'Tony', 'Damola']
age = [23, 29, 22, 27]

#use the zip() funnction to merge the two lists together 
mapped = zip(employee_names, age)

#convert the mapped object to a list
mapped = list(mapped)

#print the result
print('The result of the zip operation is:')
print()
print(mapped)

Output:

The result of the zip operation is:

[('Vash', 23), ('Ben', 29), ('Tony', 22), ('Damola', 27)]

Now let’s go over the block of code line by line. 

We started out by declaring variables to hold the employee names and their ages. Then we performed the zip() operation, passing the two lists (the employee names and age) as parameters. The zip() function does however returns an iterable object. The content of the zipped object that was returned cannot be printed to the console in a readable format. To see the readable format, you will need to convert the object into a list. Then we can print the object to return the results as seen in the output. 

For the benefit of the doubt, if I attempt to print the zipped object without converting it to a list, here’s what the output will look like. 

The result of the zip operation is:

<zip object at 0x00000250BF7A2DC8>

As you can see, it prints the object alongside its location on my machine. 

Passing Three Arguments

You can perform this same zip() function on more than two lists. Let’s say this time we want to add the department where the employee works. See the code below.

#The python code below demostrates the use of the zip() function for 3 iterables

#define the list of employees names, their age and department
employee_names = ['Vash', 'Ben', 'Tony', 'Damola']
age = [23, 29, 22, 27]
department = ['Sales', 'Finance', 'Research', 'Engineering']

#use the zip() function to merge the three lists together 
mapped = zip(employee_names, age, department)

#convert the mapped object to a list
mapped = list(mapped)

#print the result
print('The result of the zip operation is:')
print()
print(mapped)

Output:

The result of the zip operation is:

[('Vash', 23, 'Sales'), ('Ben', 29, 'Finance'), ('Tony', 22, 'Research'), ('Damola', 27, 'Engineering')]

If you are feeding the zip() functions with iterables such as dictionaries, strings, or lists, the zipping will be done from left to right. But if you zip sets datatype, the results may be unexpected as the arrangement of sets change. A set is simply a collection of unordered elements. See the code below for an example. 

#The python code below demostrates the use of the zip() function for set

#define the set of employers names, their age and department
employer_names = {'Vash', 'Ben', 'Tony', 'Damola'}
age = {23, 29, 22, 27}

#use the zip() funnction to merge the two lists together 
mapped = zip(employer_names, age)

#convert the mapped object to a list
mapped = list(mapped)

#print the result
print('The result of the zip operation is:')
print()
print(mapped)

Output:

The result of the zip operation is:

[('Ben', 27), ('Vash', 29), ('Damola', 22), ('Tony', 23)]

As seen in the output, the zip() function messes with the name and corresponding age of the employers. And that’s because they were defined as a set. This is something you should keep at the mack of your mind if you are dealing with sets. 

Passing One Argument 

Although the zip() function was built to take in two or more functions, the zip() function can still take one function without throwing an error. It returns an iterator with a series of 1-item tuples. See the code below for a demonstration. 

#The python code below demostrates the use of the zip() function with one argument
#define a list variable
a_list = [2, 4, 6, 8, 10]

#use the zip() funnction on the single list
mapped = zip(a_list)

#convert the mapped object to a list
mapped = list(mapped)

#print the result
print('The result of the zip operation is:')
print()
print(mapped)

Output:

The result of the zip operation is:

[(2,), (4,), (6,), (8,), (10,)]

Passing No Argument on the Zip Function

If you decide to pass no argument for the zip() function, the function returns an empty iterator. 

#The python code below demonstrates the use of the zip() function with no argument

#use the zip() function with no argument
mapped = zip()

#convert the mapped object to a list
mapped = list(mapped)

#print the result
print('The result of the zip operation is:')
print()
print(mapped)

Output:

The result of the zip operation is:

[]

The output was an empty list as seen above. That indicates that there was no iterable to merge. If we however, use the next() function to force the next iterator to be retrieved from the iterable object, the program yields a StopIteration exception. 

#The python code below demonstrates the use of the zip() function with no argument and calling the next() function

#use the zip() function with no argument
mapped = zip()

#call the next function on the zipped object
mapped = next(mapped)

#print the result
print('The result of the zip operation is:')
print()
print(mapped)

Output:

StopIteration                             Traceback (most recent call last)
<ipython-input-10-7cd579466771> in <module>
      5 
      6 #call the next function on the zipped object
----> 7 mapped = next(mapped)
      8 
      9 #print the result

StopIteration: 

Passing Arguments of Different Lengths

When you’re working with the zip function in python, the arguments passed are expected to be of the same length. If for some reason, you pass two iterables whose length is different, the zip function stops the zipping operation at the end of the shortest length. This means that the remaining elements of the longer iterable will be completely ignored. See an example in the block of code below. 

#The python code below demonstrates the use of the zip() function with arguments of different lengths

#define two iterables of different length
list_a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list_b = [1, 2, 3, 4, 5, 6]

#use the zip() function on list_a and list_b
mapped = zip(list_a, list_b)

#convert the zipped object into a list
mapped = list(mapped)

#print the result
print('The result of the zip operation is:')
print()
print(mapped)

Output:

The result of the zip operation is:

[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]

Notice that the zipping process stops at 6, which is the last element of list_b (the shortest iterable of the two). The remaining elements list_a were discarded. 

Using the Zip_longest Method

In a case where you care about all the elements of both iterators and do not want any element discarded, you can opt in for the zip_longest() function rather than the zip() function. 

Here’s the syntax for the zip_longest() method.

Docstring:     

Docstring:     
zip_longest(iter1 [,iter2 [...]], [fillvalue=None]) --> zip_longest object

Return a zip_longest object whose .__next__() method returns a tuple where
the i-th element comes from the i-th iterable argument.

Let’s see an example. To use the zip_longest() method, you’d need to import the itertools module. 

#The python code below demonstrates the use of the zip_longest() method to zip iterables of different length

#import the necessary library
import itertools

#define 3 lists of different lengths
list_a = [1, 2, 3]
list_b = [1, 2, 3, 4, 5, 6]
list_c = [1, 2, 3, 4, 5, 6, 7, 8, 9]

#use the zip_longest() method on list_a, list_b and list_c
mapped = itertools.zip_longest(list_a, list_b, list_c)

#convert the zipped object into a list
mapped = list(mapped)

#print the result
print('The result of the zip operation is:')
print()
print(mapped)

Output:

The result of the zip operation is:

[(1, 1, 1), (2, 2, 2), (3, 3, 3), (None, 4, 4), (None, 5, 5), (None, 6, 6), (None, None, 7), (None, None, 8), (None, None, 9)]

Using Python Zip to Loop Multiple Iterables 

The output of the zipped iterables may seem boring. Perhaps you have been wondering how the output can be used in real-life situations. This section will explain how. Using the zip() function to loop over multiple iterable is one of the most popular application of the python zip function. We will be going through the various instances in which the zip() function output can be used to produce interesting results. 

Use Case 1: Looping through lists in Parallel

Since the python zip() function returns an iterable object, the object can be looped. The returned iterable object is usually a tuple so the for loop unpacks each tuple and returns them individually. Let’s take an example. 

#The python code below demonstrates the looping of the zip() function returned iterables

#define the list of employees’ names and their age 
employee_names = ['Vash', 'Ben', 'Tony', 'Damola']
employee_ages = [23, 29, 22, 27]

#use the zip() funnction to merge the two lists together 
mapped = zip(employee_names, employee_ages)

#loop over the retunred tuple object
for name, age in mapped:
    #print the result
    print(f"{name} is {age} years old")
    print()

Output:

Vash is 23 years old

Ben is 29 years old

Tony is 22 years old

Damola is 27 years old

Notice that the for loop requires two variables since the zipped object is a tuple of 2 items, names, and ages. You can also traverse more than 2 iterables with a for loop. Consider an instance where we wish to state the departments of the employees. See the block of code below. 

#The python code below demonstrates the looping of the zip() function returned iterables

#define the list of employees names, their age and department 
employee_names = ['Vash', 'Ben', 'Tony', 'Damola']
employee_ages = [23, 29, 22, 27]
employee_departments = ['Sales', 'Finance', 'Research', 'Engineering']

#use the zip() funnction to merge the three lists together 
mapped = zip(employee_names, employee_ages, employee_departments)

#traverse the three iterable object
for name, age, department in mapped:
    #print the result
    print(f"{name} is {age} years old and works in the {department} department")
    print()

Output:

Vash is 23 years old and works in the Sales department

Ben is 29 years old and works in the Finance department

Tony is 22 years old and works in the Research department

Damola is 27 years old and works in the Engineering department

You can carry out the same procedure for more than 3 iterables as well. There’s no limitation to the number of iterables that python zip function can be looped over. 

Use Case 2: Looping Over Dictionaries in Parallel

Dictionaries are another type of iterable objects. They are ordered collections with key-value pairs. You can use the Python zip() function to loop over more than one dictionary without messing with the key-value pair’s arrangement. 

#The python code below demonstrates the looping of the zip() function on dictionaries

#define the dictionary of different employees
employee_1 = {'name': 'Vash', 'age': 23}
employee_2 = {'name': 'Ben', 'age': 29}
employee_3 = {'name': 'Tony', 'age': 22}
employee_4 = {'name': 'Damola', 'age': 27}


#use the zip() funnction to merge the 4 dictionaries together 
mapped = zip(employee_1.values(), employee_2.values(), employee_3.values(), employee_4.values())

#loop over the retunred tuple object
for (value1, value2, value3, value4) in mapped:
    print(value1, value2, value3, value4)

Output:

Vash Ben Tony Damola
23 29 22 27

Let’s go over the code since it looks relatively bulkier. We defined a dictionary with two keys called, name and age for all four employees. A python dictionary has a key-value pair connection in this form – {key: value}. The keys can be accessed separately using the .keys() methods whereas the values can be accessed using the .values() method.

Since we care about the value alone, the python zip() function is passed on the values of the dictionary. 

Then for loop is used to iterate the returned tuple object and is printed to the console. 

More Variations

If we want to iterate over both the keys and the values of the dictionary, we must use the .items() method when zipping the dictionaries. The returned tuple object in this case would be a list of tuples containing the keys and values. See the example below. 

#The python code below demonstrates the looping of the zip() function on dictionaries

#define the dictionary of different employees
employee_1 = {'name': 'Vash', 'age': 23}
employee_2 = {'name': 'Ben', 'age': 29}
employee_3 = {'name': 'Tony', 'age': 22}
employee_4 = {'name': 'Damola', 'age': 27}


#use the zip() function to merge the 4 dictionaries together 
mapped = zip(employee_1.items(), employee_2.items(), employee_3.items(), employee_4.items())

#print the tuple of both dictionary keys and values
print(list(mapped))

Output:

[(('name', 'Vash'), ('name', 'Ben'), ('name', 'Tony'), ('name', 'Damola')), (('age', 23), ('age', 29), ('age', 22), ('age', 27))]

Traver

Traversing the Tuple Object

You can iterate the tuple object with a for loop. 

#loop over the returned tuple object

for (key1, value1), (key2, value2), (key3, value3), (key4, value4) in mapped:
    print(f"{key1} ==> {value1}")
    print(f"{key2} ==> {value2}")
    print(f"{key3} ==> {value3}")
    print(f"{key4} ==> {value4}")

Output:

name ==> Vash
name ==> Ben
name ==> Tony
name ==> Damola
age ==> 23
age ==> 29
age ==> 22
age ==> 27

The same procedure for zipping and looping through dictionaries also applies for sets. However, the order of the set elements may be altered as explained earlier. If you are concerned about the order of the elements of the iterator, err on the side of caution by using dictionaries. 

Unzipping in Python with the Zip Function

Yes. There was no mistake – unzipping with the zip function. Thus far, we have spoken extensively about the zip function in detail . But you are as inquisitive as I am, you must be asking yourself, is there a function to unzip, perhaps an unzip function? That’s a valid question. While you can unzip in python, there is no separate function dedicated for unzipping. 

You simply unzip with the same zip function in python. However, you specify that you wish to unpack the iterable by using the unpacking operator, *. Let’s see an example. Say we have zipped three lists zipped. 

#The python code below demonstrates the how to unpack a zipped iterator

#define the list of employees names, their age and department 
employee_names = ['Vash', 'Ben', 'Tony', 'Damola']
employee_ages = [23, 29, 22, 27]
employee_departments = ['Sales', 'Finance', 'Research', 'Engineering']

#use the zip() funnction to merge the three lists together 
mapped = zip(employee_names, employee_ages, employee_departments)

print(list(mapped))

Output:

[('Vash', 23, 'Sales'), ('Ben', 29, 'Finance'), ('Tony', 22, 'Research'), ('Damola', 27, 'Engineering')]

We can unpack this by using the unpack operating. Going forward, you can print the individual list to the console 

#unpacked the zipped list
names, ages, depts = zip(*list(mapped))

#print the individual lists
print(names)
print()
print(ages)
print()
print(depts)

Output:

('Vash', 'Ben', 'Tony', 'Damola')

(23, 29, 22, 27)

('Sales', 'Finance', 'Research', 'Engineering')

Doing Some Calculations with the Zip Function

You can also make use of the zip function to aid some basic calculations. Let’s say we have data that records the time it takes for a car to travel some distance. If we wish to calculate the average speed of the car, we can simply divide the distance by the time taken. Let’s see how we can use the zip function to aid our calculation. 

#The python code below demonstrates how the zip() function can aid mathematical computations

#define the distance and time for the cars in km and hr respectively
distance = [24, 11, 14, 9]
time = [1.5, 0.8, 1, 1.2]
#use the zip() function to merge the distance and time
mapped = zip(distance, time)

#loop over the returned tuple object
for dist, tm in mapped:
    speed = dist / tm
    print(f"The speed of the is {speed} km/hr")

Output:

The speed of the is 16.0 km/hr
The speed of the is 13.75 km/hr
The speed of the is 14.0 km/hr
The speed of the is 7.5 km/hr

In Summary

In this tutorial, we have discussed how to use Python’s zip() function for myriad purposes. You have learned how to use the python zip function with the typical case of two or more iterables, sometimes one iterables and even with no argument passed. 

Furthermore, you understood how the zip function behaves when you pass iterables of different lengths. 

In addition, you learned how to loop through multiple iterables. Also, you discovered how to use the unzip a zipped object and how to do basic calculations with the python zip function. 

  • Here are some key take-homes.
  • The python zip function returns an object in python 3. 
  • You can iterate the returned object with a for loop to access the elements individually
  • To print the zipped object, you have to convert it to a list, set, or dictionary.
  • Finally, do not forget that a set is an unordered collection which implies that when you zip a set, the order of the elements is unpredictable.

Leave a Comment

Pin It on Pinterest