Python zip() Method

The zip() method takes one or more iterables (such as list, tuple, string, etc.) and constructs the iterator of tuples where each tuple contains elements from each iterable.

Syntax:

zip(*iterables)

Parameters:

iterables: Can be built-in iterables or user defined iterables.

Return type:

Returns zip object that works as an iterator.

The following example returns an iterator of tuples for the specified lists.

Example: zip()
numbers = [1,2,3]
str_numbers = ['One','Two','Three']
result = zip(numbers, str_numbers)
print(result)
print(list(result))
Output
<zip object at 0x0000014EC4A6B788>
[(1, 'One'), (2, 'Two'), (3, 'Three')]

Any number of iterables can be passed as arguement in the zip() method.

Example: zip()
numbers = [1,2,3]
str_numbers = ['One','Two','Three']
roman_numbers = ['I','II','III']
result = zip(numbers, str_numbers, roman_numbers)
print(result)
print(list(result))
Output
<zip object at 0x0000014EC4A90508>
[(1, 'One', 'I'), (2, 'Two', 'II'), (3, 'Three', 'III')]

The zip object can be cast to a list of tuples. Each tuple will have corresponding elements from both list parameters.

Example: zip()
teams = ["India", "England", "NZ", "Aus"]
captains = ["Kohli","Root","Williaamson", "Smith"]
zipped = zip(teams,captains)
ziplist = list(zipped)
print(ziplist)
Output
[('India', 'Kohli'), ('England', 'Root'), ('NZ', 'Williaamson'), ('Aus', 'Smith')]

It can also be cast to a dictionary.

Example: Zip to Dictionary
zipped = zip(teams,captains)
zipdict = dict(zipped)
print(zipdict)
Output
{'India': 'Kohli', 'England': 'Root', 'NZ': 'Williaamson', 'Aus': 'Smith'}

Since the zip object is an iterator, it can be traversed with the next() function until the StopIteration exception is reached.

Example: Using zip Object in Loop
teams=["India", "England", "NZ", "Aus"]
captains=["Kohli","Root","Williaamson", "Smith"]
zipped=zip(teams,captains)
while True:
    try:
        tup=next(zipped)
        print(tup[0],"->", tup[1])
    except StopIteration:
        break
Output
India -> Kohli
England -> Root
NZ -> Williaamson
Aus -> Smith

As we can see, n'th tuple in zip object contains corresponding n'th element from iterable parameters. It means if zipped = zip (x, y, z) then zipped = [(x0, y0, z0), (x1, y1, z1), (x2, y2, z2), . . .]

But what if the iterable parameters are not equal in length?

In the following example, three strings of unequal length are given as parameters to the zip() function:

Example: zip()
s1 = "Java"
s2 = "Python"
s3 = "PHP"
print(list(zip(s1, s2, s3)))
Output
[('J', 'P', 'P'), ('a', 'y', 'H'), ('v', 't', 'P')]

As we see, the zip iterator collects characters from each string till characters in a shortest string are exhausted. If you want to include unmatched characters from the other two strings in the zipped object, use zip_longest() function defined in itertools module.

Example: zip_longest()
import itertools
s1 = "Java"
s2 = "Python"
s3 = "PHP"
print(list(itertools.zip_longest(s1,s2,s3)))
Output
[('J', 'P', 'P'), ('a', 'y', 'H'), ('v', 't', 'P'), ('a', 'h', None), (None, 'o', None), (None, 'n', None)]

Instead of None, any other character can be specified as fillvalue parameter.

Example: zip_longest()
print(list(itertools.zip_longest(s1,s2,s3, fillvalue='?')))

The zip() function proves useful in cases like parallel traversal and sorting of lists. In the following example, two lists - one for the items and other for their prices is used. We have to prepared a combined list sorted on the basis of price.

Example:
items = ['book', 'keyboard','pen', 'mouse']
price = [325, 500, 75, 250]
sortedlist = sorted(list(zip(price,items)))
print(sortedlist)
Output
[(75, 'pen'), (250, 'mouse'), (325, 'book'), (500, 'keyboard')]

Another application of the zip() function is when corresponding values of lists have to be used in some processing. In the following example, sales is a list of sales amounts of some products, and rates is a list of rates at which GST is to be calculated.

Example:
sales = [2500, 15000, 7800, 5000]
rates = [15, 10, 8, 10]
combined = list(zip(sales, rates))
for s,r in combined:
    gst=s*r/100
    print("sales:{} rate:{} GST:{}".format(s,r,gst))
Output
sales:2500 rate:15 GST:375.0
sales:15000 rate:10 GST:1500.0
sales:7800 rate:8 GST:624.0
sales:5000 rate:10 GST:500.0

Unzipping Zip Object

Python doesn't have a separate function for unzipping a zipped object in separate tuples. The zip() function itself, when used with * (the unpacking operator), is used for unzip operation.

Example: Unzipping using * Operator
digits = [1,2,3,4,5]
words = ['one', 'two', 'three', 'four','five']
zipobj = zip(digits, words)
## to unzip
x,y = zip(*zipobj)
print(x)
print(y)
Output
(1, 2, 3, 4, 5)
('one', 'two', 'three', 'four', 'five')