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.