Python zip() Function

python zip() function

The zip() function in Python is a neat little function that takes two or more sequences as inputs and allows you to iterate through those sequences at the same time. To show how zip() can be used when in your programs, we’ll take a look at several examples of zip() in this tutorial. When we say iterables we are referring to the various iterables in Python such as a list, tuple, string, etc. Let’s get started with some examples of the zip() function now.


zip() Example one

meats = ['Steak', 'Pork', 'Duck', 'Turkey']
toppings = ['Butter', 'Garlic', 'Olive Oil', 'Cranberry']
for meat, topping in zip(meats, toppings):
    print(f'{meat} topped with {topping}')
Steak topped with Butter
Pork topped with Garlic
Duck topped with Olive Oil
Turkey topped with Cranberry

zip() Example two

numbers = [1, 2, 3, 4]
str_numbers = ['One', 'Two', 'Three', 'Four']
result = zip(numbers, str_numbers)
print(result)
print(list(result))

[(1, 'One'), (2, 'Two'), (3, 'Three'), (4, 'Four')]

zip() with Dictionary

colors = ['Red', 'White', 'Blue']
cars = ['Corvette', 'Bronco', 'Mustang']

my_dict = {}
for color, car in zip(colors, cars):
    my_dict[color] = car
print(my_dict)
{'Red': 'Corvette', 'White': 'Bronco', 'Blue': 'Mustang'}

Calling zip() with no iterable

result = zip()
print(result)
<zip object at 0x0000025021AD51C0>

Passing more than two iterables to zip()

numerals = [1, 2, 3]
str_numerals = ['One', 'Two', 'Three']
roman_numerals = ['I', 'II', 'III']
result = zip(numerals, str_numerals, roman_numerals)
print(list(result))
[(1, 'One', 'I'), (2, 'Two', 'II'), (3, 'Three', 'III')]

Cast zip object to list of tuples

states = ['Massachusetts', 'Colorado', 'California', 'Florida']
capitals = ['Boston', 'Denver', 'Sacremento', 'Tallahassee']
zipped = zip(states, capitals)
ziplist = list(zipped)
print(ziplist)
[('Massachusetts', 'Boston'), ('Colorado', 'Denver'), ('California', 'Sacremento'), ('Florida', 'Tallahassee')]

Cast zip object to a dictionary

states = ['Massachusetts', 'Colorado', 'California', 'Florida']
capitals = ['Boston', 'Denver', 'Sacremento', 'Tallahassee']
zipped = zip(states, capitals)
zipdict = dict(zipped)
print(zipdict)
{'Massachusetts': 'Boston', 'Colorado': 'Denver', 'California': 'Sacremento', 'Florida': 'Tallahassee'}

Using zip() with the Python next() function

states = ['Massachusetts', 'Colorado', 'California', 'Florida']
capitals = ['Boston', 'Denver', 'Sacremento', 'Tallahassee']
zipped = zip(states, capitals)
while True:
    try:
        tup = next(zipped)
        print(tup[0], "capital is", tup[1])
    except StopIteration:
        break
Massachusetts capital is Boston
Colorado capital is Denver
California capital is Sacremento
Florida capital is Tallahassee

How to unzip a zipped object

states = ['Massachusetts', 'Colorado', 'California', 'Florida']
capitals = ['Boston', 'Denver', 'Sacremento', 'Tallahassee']
zipped = zip(states, capitals)
print(zipped)

first, second = zip(*zipped)
print(first)
print(second)
<zip object at 0x000001A6ED61E1C0>
('Massachusetts', 'Colorado', 'California', 'Florida')
('Boston', 'Denver', 'Sacremento', 'Tallahassee')

Different length iterables

All of the examples we have looked at so far use iterables that all have the same number of elements in them. What happens when you try to use the zip() function on iterables where one is longer than the other? The default behavior for Python is to limit the operation to the smaller-sized iterable. Here is an example where one iterable has 3 elements and the other has five.

one = [1, 2, 3, 4, 5]
two = ['a', 'b', 'c']

result = zip(one, two)
print(list(result))
[(1, 'a'), (2, 'b'), (3, 'c')]

If you would want to change the behavior so that the longer of the iterables is used, you can use the zip_longest() function which is part of the itertools package.

import itertools as it

one = [1, 2, 3, 4, 5]
two = ['a', 'b', 'c']

result = it.zip_longest(one, two)
print(list(result))
[(1, 'a'), (2, 'b'), (3, 'c'), (4, None), (5, None)]

You can see that the zip_longest() function simply inserts a value of None for the slots where an empty value exists due to the different sized iterables. If you would like to specify a different value, you can make use of the fillvalue parameter like so.

import itertools as it

one = [1, 2, 3, 4, 5]
two = ['a', 'b', 'c']

result = it.zip_longest(one, two, fillvalue='­čśŐ')
print(list(result))
[(1, 'a'), (2, 'b'), (3, 'c'), (4, '­čśŐ'), (5, '­čśŐ')]

Python zip() Function Summary

The zip() function takes iterables and aggregates them into a tuple and returns it.

The syntax of the zip() function is:

zip(*iterables)

The iterables parameter can be built-in iterables such as list, string, dict, or user-defined iterables.

The zip()function returns an iterator of tuples based on the iterable objects.

  • If we do not pass any parameter,┬ázip()┬áreturns an empty iterator
  • If a single iterable is passed,┬ázip()┬áreturns an iterator of tuples with each tuple having only one element.
  • If multiple iterables are passed,┬ázip()┬áreturns an iterator of tuples with each tuple having elements from all the iterables.

    Suppose, two iterables are passed to┬ázip(); one iterable containing three and other containing five elements. Then, the returned iterator will contain three tuples. It’s because iterator stops when the shortest iterable is exhausted.