Zip in Python | Zip Function in Python
Overview
The zip() function in python is an in-built function that takes any number of iterables(list, str, etc.) as an argument and aggregate them together by taking elements from each iterable passed as argument.
It stops when the shortest iterable is exhausted and the elements in longer iterables are left out. It is mostly used to iterate through multiple iterables.
Syntax of zip() function in Python
The syntax of zip() function is as follows,
The * means that zip can take a variable number of iterables as arguments. Thus, zip(*iterables) means zip(iterable1, iterable2, iterable3, ...).
Parameters of zip() function in Python
Any number of built-in (list, dict, string) or user-defined iterables.
Return value of zip() function in Python
Return Type: <class 'zip'>
The zip function returns a zip object which is an iterator of tuples with values derived from the iterables passed as arguments.
Example of zip() function in Python
Output:
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 passed 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.
What is 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.
It takes corresponding elements from all the iterable passed to it and merges them in a tuple.
Note: Tuples are immutable data structures defined with parenthesis that store 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 them 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() function, you must know:
- An iterable is an object of a series of elements that can be iterated.
For example, a list is an iterable:
- 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.
Output:
- 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.
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) = [(a0, b0), (a1, b1), (a2, b2), ...]
It stops when the shortest iterable is exhausted, and the elements in longer iterables are left out.
More Examples
Let's review some examples of how to use zip functions for a better understanding.
Example 1: Using Python zip() function with two lists
Let's start with the most simple one, zipping two lists of the same length:
Output:
Explanation:
Both numbers and square are of the same length. Therefore the zipped list num_square is also of the same length 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:
Output:
Explanation:
The zip function returns an empty iterator when no iterable is passed, thus, it is converted into an empty list in python.
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:
Output:
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:
Output:
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?
Output:
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: Usage of 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:
Output:
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.
We can provide another default value using the fillvalue parameter:
Output:
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:
Output:
Explanation:
The * operator is the unpacking operator, it unpacked the country_capital list into separate tuples. so writing zip(*country_capital) was equivalent to:
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:
Output:
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.
Output:
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.
Example 10: Looping Over Multiple Iterables Using Zip Function in Python
You can loop through a single iterable using a for loop:
But what if you need to loop over multiple iterables? You may use the range function to do this:
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:
Output:
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.
Example 11: 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/Stock | Stock 1 | Stock 2 | Stock 3 |
---|---|---|---|
Buy Price | 50 | 70 | 30 |
Sell Price | 80 | 65 | 120 |
Now you need to calculate your net profit. You can use the zip function as follows to do it quickly:
Output:
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.
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.
- 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 returned iterator has the length of the shortest iterable.
- 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.
- 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.
- We can loop through multiple iterables conveniently using the zip function.
- We need to convert a zip object into a list to use it multiple times or to print it onto the console.