Search for Hubs, Articles and Topics
Search for Hubs, Articles and Topics

# Zip in Python | Zip Function in Python

Learn about Zip Function in Python.

## Abstract

The zip function in python is an in-built function that takes any number of iterables as an argument and returns a zip object which is an iterator of tuples. It is mostly used to iterate through multiple iterables.

## Introduction to Zip Function in Python

Very often in programming, we need to loop through multiple sequences together.

For instance, if you have two lists:

• countries: list of names of the countries.
• capitals: list of capital cities of those countries.

Now, you need to iterate over both lists and print the following line for each combination: capital of {country} is {capital}.

Python provides the zip function for this exact purpose.

Zip is an in-built function in Python used to iterate over multiple iterables together.

It takes corresponding elements from all the iterables passed to it and merges them in a tuple.

Note: Tuples are immutable data structures defined with parenthesis that stores an ordered sequence of values. For example: (1, 2, 3) is a tuple with three values. As tuples are immutable, you can not change the values inside it after it is defined.

The following figure illustrates the same:

• The zip function took a list of countries and a list of capitals.
• Then merged their corresponding elements in a tuple.
• That means the ith tuple has ith elements from both the list.

To understand zip, you must know:

• An iterable is an object of a series of elements that can be iterated over. For example, a list is an iterable:
l = [1, 2, 3, 4, 5, 6]


• An iterator is an object used to iterate over an iterable.
• We can generate an iterator object using the iter method on an iterable.
• Use the next function to get a value from an iterable using an iterator. Example:
l = [1, 2, 3, 4, 5, 6]

iterator = iter(l)    # Creating an iterator
print(next(iterator)) # Getting value from iterable
print(next(iterator))


Output:
1
2


• Note 📝: An iterator object exhaust and raise the StopIteration error once all the values underneath the iterable are read.
• Fun Fact 💡: When you are using a for loop to iterate over a list, it is using an iterator underneath to perform the looping.

In the following sections, you will learn how to use the zip function to loop through multiple iterables, how it works and several examples to make things clear.

### Syntax of Zip in Python

Syntax: zip(*iterables)

Note 📝: The * means that zip can take a variable number of iterables as arguments. Thus, zip(*iterables) means zip(iterable1, iterable2, iterable3, ...).

## Python Zip Function Parameters

ParameterDescription
iterablesAny number of built-in (list, dict, string) or user-defined iterables.

## Python Zip Function Return Value

The zip function returns a zip object which is an iterator of tuples with values derived from the iterables passed as argument. This zip object can be used to loop over the tuples or we can convert it to a list.

Takeaways:

• Zip is an in-built function that creates an iterator of tuples by combining iterables.
• It can take any number of iterables as an argument.

## How to Use Python's Zip Function

Consider the following example:

countries = ["India", "UK", "USA", "Canada"]
capitals = ["Delhi", "London", "Washington DC", "Ottawa"]

country_capital = zip(countries, capitals)

print(country_capital)
print(list(country_capital))



Output:

<zip object at 0x7fce6586fb40>
[('India', 'Delhi'), ('UK', 'London'), ('USA', 'Washington DC'), ('Canada', 'Ottawa')]



Explanation:

Let's go through the code line by line:

• We first created two lists: countries and capitals.
• As you can see, the ith city is the capital of ith country.
• For example, the 0th element of capitals (Delhi) is the capital city of the 0th element of the countries (India).
• Then, we are passing both the lists to the zip function to combine them into a single list of tuples of the format (country, capital).
• The zip function returns an iterator of tuples which we stored in the variable country_capital.
• We need to convert the zip object into a list to print on the console.

## How Python's Zip Function Works

Let's understand the internal working of the zip function:

• The zip function first calculates the number of iterables passed as argument.
• Then, it calculates the minimum common length of all iterables. Let's call this num_items.
• Then, it creates a new list of length num_items which will contain tuples consisting of elements from all the iterables passed to the zip function. Let's call it return_list.
• Then, the zip function creates an iterator for each iterables passed to it.
• After that, the zip function iterate over return_list and in each position i, add the elements from the ith position of all of iterables passed to zip function. This is done by using the iterators created in the previous step.
• Finally, the return_list is returned.
• Note: The zip function also performs some checks for edge cases and data types.

## How the Zip Function Creates an Iterator of Tuples

The zip function creates an iterator of tuple by taking elements from each iterable passed as argument and aggregating them together:

zip(a, b) = [($a_0$, $b_0$), ($a_1$, $b_1$), ($a_2$, $b_2$), ...]

It stops when the shortest iterable is exhausted and the elements in longer iterables are left out.

Takeaways

• The zip function aggregate ith element of every iterable in a tuple.
• You need to convert a zip object into a list to use it multiple times or to print it onto the console.

## Example of Zip Function in Python

Let's go over some examples of how to use zip functions for a better understanding.

### Example 1: Python zip()

Let's start with the most simple one, zipping two lists of the same length:

numbers = [1, 2, 3, 4, 5]
square = [1, 4, 9, 16, 25]

num_square = zip(numbers, square)

print(list(num_square))



Output:

[(1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]



Explanation: Both numbers and square are of the same length. Therefore the zipped list num_square is also of the same length that is 5. Thus, Corresponding elements are merged in a tuple of size 2 and no element is left out.

### Example 2: No iterable Passed to Zip Function

What if we pass no iterable to the zip function? Let's try it out:

empty_zipped = zip()

print(list(empty_zipped))



Output:

[]



Explanation: The zip function returns an empty iterator when no iterable is passed, thus it is converted into an empty list and hence the output is that.

### Example 3: One Iterable Passed to Zip Function

Let's see what is the output when we pass only one iterable to the zip function:

countries = ["India", "UK", "USA", "Canada"]
single_zipped = zip(countries)

print(list(single_zipped))



Output:

[('India',), ('UK',), ('USA',), ('Canada',)]



Explanation: Because only one iterable is passed, the zip function returned an iterator of tuples with length 1. Therefore, the output is a list with tuples of size 1 where each element is taken from the single iterable countries.

### Example 4: Multiple iterables Passed to Zip Function

Till now, we have only passed one or two iterables to the zip function, but there is no limit to that. Let's try passing three iterables now:

countries = ["India", "UK", "USA", "Canada"]
capitals = ["Delhi", "London", "Washington DC", "Ottawa"]
dial_code = ["+91", "+44", "+1", "+1"]

country_capital = zip(countries, capitals, dial_code)

print(list(country_capital))



Output:

[('India', 'Delhi', '+91'), ('UK', 'London', '+44'), ('USA', 'Washington DC', '+1'), ('Canada', 'Ottawa', '+1')]



Explanation: Now we have 3 iterables - countries, capitals, dial_code with 4 elements each. Thus, the zipped list will have 4 tuples of size 3 each.

### Example 5: Iterables of different length

What if one iterable has fewer elements than the others?

countries = ["India", "UK", "USA", "Canada"]
capitals = ["Delhi", "London"]

country_capital = zip(countries, capitals)

print(list(country_capital))



Output:

[('India', 'Delhi'), ('UK', 'London')]



Explanation: The zip function returned an iterator of two tuples because the iterator stops when the shortest iterable is exhausted and the elements in longer iterables are left out. In this case, the capitals iterable which has two elements is exhausted before the countries iterable. Therefore the zipped list has all the elements from capitals but the last 2 elements of countries - USA and Canada are left out.

### Example 6: zip_longest()

If you want to zip all elements even when the shortest iterable is exhausted, you can use the zip_longest function from the itertools library:

from itertools import zip_longest

countries = ["India", "UK", "USA", "Canada"]
capitals = ["Delhi", "London"]

country_capital = zip_longest(countries, capitals)

print(list(country_capital))



Output:

[('India', 'Delhi'), ('UK', 'London'), ('USA', None), ('Canada', None)]



Explanation: zip_longest merges elements from each of the iterables. If the iterables are of uneven length, missing values are filled in with the default value of None. Iteration continues until the longest iterable is exhausted. You can provide another default value using the fillvalue parameter:

from itertools import zip_longest

countries = ["India", "UK", "USA", "Canada"]
capitals = ["Delhi", "London"]

country_capital = zip_longest(countries, capitals, fillvalue="Capital Missing")

print(list(country_capital))



Output:

[('India', 'Delhi'), ('UK', 'London'), ('USA', 'Capital Missing'), ('Canada', 'Capital Missing')]



### Example 7: Unzipping the values using zip()

There is no special function to unzip zipped iterables, you can use the zip function with the * operator to unzip a zip object:

countries = ["India", "UK", "USA", "Canada"]
capitals = ["Delhi", "London", "Washington DC", "Ottawa"]

# Zip countries & capitals together
country_capital = list(zip(countries, capitals))

print(country_capital)

# Unzip country_capitals into separate iterables
countries_unzipped, capitals_unzipped = zip(*country_capital)

print(countries_unzipped)
print(capitals_unzipped)



Output:

[('India', 'Delhi'), ('UK', 'London'), ('USA', 'Washington DC'), ('Canada', 'Ottawa')]
('Delhi', 'London', 'Washington DC', 'Ottawa')



Explanation: The * operator is the unpacking operator, it unpacked the country_capital list into separate tuples that become the argument to the zip function, so writing zip(*country_capital) was equivalent to:

zip(('India', 'Delhi'), ('UK', 'London'), ('USA', 'Washington DC'), ('Canada', 'Ottawa'))



These tuples acted as iterables to be zipped again. Thus giving an iterator of two tuples as output with 4 members each.

### Example 8: Converting Zip Object into a Dictionary

A zip object with a tuple of size 2 can be converted to a dictionary:

countries = ["India", "UK", "USA", "Canada"]
capitals = ["Delhi", "London", "Washington DC", "Ottawa"]

country_capital = zip(countries, capitals)

country_capital_dict = dict(country_capital)
print(country_capital_dict)



Output:

{'India': 'Delhi', 'UK': 'London', 'USA': 'Washington DC', 'Canada': 'Ottawa'}



Explanation:

It is possible because the dict function accepts an iterable of tuples for dictionary creation.

A tuple of size two provides a (key, value) pair for the dictionary.

### Example 9: Using Zip Object in a Loop

As a zip object is an iterator, it can be traversed with the next function until the StopIteration exception is reached.

countries = ["India", "UK", "USA", "Canada"]
capitals = ["Delhi", "London", "Washington DC", "Ottawa"]

country_capital = zip(countries, capitals)

while True:
try:
country, capital = next(country_capital)
print("Capital of", country, "is", capital)
except StopIteration:
break



Output:

Capital of India is Delhi
Capital of UK is London
Capital of USA is Washington DC



Explanation: The next function is provided by any iterator for traversal and once the iterator is exhausted, a StopIteration Exception is raised. We can use these two together for traversing a zip object with a while loop.

Note: In the next section, you will find a more convenient way to loop through a zip object.

Takeaways

• Zip returns an empty iterator when no argument is passed.
• Zip returns an iterator of a single value tuple when a single argument is passed.
• When n number of iterables are passed, each tuple has n number of elements.
• When passed iterables have different lengths, the iterator has the length of the shortest iterable.
• We can use zip_longest to zip all elements regardless of the shortest iterable.
• We can unzip a zip object using the * operator and zip function.
• A zip object can be converted to a dict.
• We can use a zip object in a while loop with the next function and StopIteration exception.

## Looping Over Multiple Iterables Using Zip Function in Python

You can loop through a single iterable using a for loop:

countries = ["India", "UK", "USA", "Canada"]

for country in countries:
print(country)



But what if you need to loop over multiple iterables? You may use the range function to do this:

countries = ["India", "UK", "USA", "Canada"]
capitals = ["Delhi", "London", "Washington DC", "Ottawa"]

for index in range(len(countries)):
print("Capital of", countries[index], "is", capitals[index])



Explanation: In this method, we are using the range method to loop through numbers from 0 to the length of a list and inside the loop, we are using that number as an index for accessing values from the list.

But this method is not the best option available to us. First, it is not very readable. Second, it may cause IndexError if we used the shorter list inside the len function.

The better choice would be to use the zip function as below:

countries = ["India", "UK", "USA", "Canada"]
capitals = ["Delhi", "London", "Washington DC", "Ottawa"]

for country, capital in zip(countries, capitals):
print("Capital of", country, "is", capital)



Output:

Capital of India is Delhi
Capital of UK is London
Capital of USA is Washington DC



Explanation: We are using the zip function to create an iterator of tuple with corresponding values from both the iterable and then unpacking them into separate variables: country & capital.

Takeaway

• We can loop through multiple iterables conveniently using the zip function.

## Real-Life Application of Zip Function

The zip function can be used for quick calculations. Suppose you have the following data about three stocks you owned:

Price/StockStock 1Stock 2Stock 3
Sell Price8065120

Now you need to calculate your net profit. You can use the zip function as follows to do it quickly:

buy_prices = [50, 70, 30]
sell_prices = [80, 65, 120]

profit = 0



Output:

Your net profit is 115



Explanation: We created two lists for buy price and sell price. Then assigned the profit to 0 initially. We used the zip function to iterator over both lists easily in the for loop and calculated profit by subtracting sell price and buy price and then adding that value to the previous value of profit using the += operator. Finally, we printed the net profit.

Takeaway

• The zip function can be used for making quick calculations on different but related data.

## Conclusion

• Zip is a useful in-built function provided by Python to loop through multiple iterables.
• Zip takes any number of iterables and returns a zip object which is an iterator of tuples.
• Each ith tuple inside the zip object has ith element from each iterable.
• We saw multiple examples of using the zip function.
• We can use the zip_longest function to zip all elements of all iterables.
• We can unzip a zip object using the * operator and zip function.
• We learned to loop through multiple iterables conveniently using the zip function and how it can be helpful to make quick calculations.