Python zip() function

The Python zip() function purpose is to generate an iterator containing all the elements from the iterable object pass to it.

The function zip() has the fromat.

zip( *iterable )

Return type

The function returns an iterator of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables. The iterator stops when the shortest input iterable is exhausted. With a single iterable argument, it returns an iterator of 1-tuples. With no arguments, it returns an empty iterator.

To simplify the above statement zip() returns a tuple containing elements of each of the iterable(like list,tuple,string,etc.) pass to it as an argument.The elements contain in the tuple return by the function are ordered exactly the same way as it is found in the iterables.

Consider the code below.

>>> strin="TExt"
>>> tp=tuple( zip(strin) ) #tuple created from string
>>> tp 
(('T',), ('E',), ('x',), ('t',))
>>> tp1=tuple( zip( dic ) ) #tuple created from dictionary 
>>> tp1
(('new',), ('text',), ('Heap',))

Above we have created tuple from string and dictionary object using the tuple() and zip() function.Note also the elements of tp and tp1 are tuple itself.If you want to create list instead of tuple then feed whatever is return by zip() to list() and the output is list object.

Now let us try passing two or more iterable object to zip() function.

>>> strin="TExt"
>>> lst=[12 ,67 ,89 ,90]
>>> tp=tuple( zip(lst, strin) )
>>> tp
((12, 'T'), (67, 'E'), (89, 'x'), (90, 't'))
>>> #Creating list 
>>> ls=list( zip(lst, strin) )
>>> ls
[(12, 'T'), (67, 'E'), (89, 'x'), (90, 't')]
>>> #Creating dictionary
>>> dic=dict( zip(lst, strin) )
>>> dic
{12: 'T', 67: 'E', 89: 'x', 90: 't'}
>>> #Passing three iterables to zip()
>>> tp1=(23 ,56 ,78 ,90)
>>> lst1=list( zip( lst , strin, tp1 ) ) 
>>> lst1
[(12, 'T', 23), (67, 'E', 56), (89, 'x', 78), (90, 't', 90)]

So you see the purpose of zip() function is to create a tuple out of each of the elements of the iterable pass to the function with each of the order of elements pertaining to the order found in their original sequence.

Passing no iterable to zip()

If no iterable is pass to zip() then the function return an empty iterator.The empty iterator return by the function is equivalent to.

def zip(*iterables):
    # zip('ABCD', 'xy') --> Ax By
    sentinel = object()
    iterators = [iter(it) for it in iterables]
    while iterators:
        result = []
        for it in iterators:
            elem = next(it, sentinel)
            if elem is sentinel:
        yield tuple(result)

Unzipping the zipped tuple

Ok so we have called upon zip() to generate a list of tuple in our program.But now the program demands that we unzipped the list of tuple and revert everything back to their original sequence.The process for this is quite simple unexpectedly.

To unzipped everything we will call the zip() function again but this time the argument is the zip() function itself containing the iterables passed and also the operator ‘*’ is included before the argument zip() .A code example is given below.

>>> strin="TExt"
>>> lst=[12 ,67 ,89 ,90]
>>> tp1=(23 ,56 ,78 ,90)
>>> list( zip( lst , strin, tp1 ) )
[(12, 'T', 23), (67, 'E', 56), (89, 'x', 78), (90, 't', 90)]
>>> #Unzipping 
>>> ls12 , st , tpp =zip( *zip(lst , strin , tp1) )
>>> list( ls12 )
[12, 67, 89, 90 ]
>>> tuple( tpp)
(23, 56, 78, 90)

It’s simple,isn’t?

How to use zip() function with Python for loop is shown here Iterating over multiple sequence