zip
zip()
: creates an iterator that will aggregate elements from two or more iterables.
According to the official documentation, Pythonโs zip()
function behaves as follows:
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.
Python zip operations work just like the physical zipper on a bag or pair of jeans. Interlocking pairs of teeth on both sides of the zipper are pulled together to close an opening.
Use zip()
in python
zip(*iterables)
:
takes in iterables as arguments and returns an iterator
generates a series of tuples containing elements from each iterable
can accept any type of iterable, such as files, lists, tuples, dictionaries, sets, and so on.
Pass n arguments
# Pass n arguments
numbers = [1, 2, 3]
letters = ['a', 'b', 'c']
upper_letters = ['A', 'B', 'C']
zipped = zip(numbers, letters, upper_letters)
zipped
<zip at 0x62479ae08>
list(zipped)
[(1, 'a', 'A'), (2, 'b', 'B'), (3, 'c', 'C')]
num_tuple = (1, 2)
lettet_tuple = ('a', 'b')
upper_letter_tuple = ('A', 'B')
list(zip(num_tuple, lettet_tuple, upper_letter_tuple))
[(1, 'a', 'A'), (2, 'b', 'B')]
Pass no arguments
# Passing no argument
zipped = zip()
zipped
<zip at 0x62473c908>
list(zipped)
[]
Pass one arguments
# Pass one argument
zipped = zip(numbers)
list(zipped)
[(1,), (2,), (3,)]
Pass arguments of unequal length:
the number of elements that zip()
puts out will be equal to the length of the shortest iterable. The remaining elements in any longer iterables will be totally ignored by zip()
list(zip(range(5), range(100)))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
If trailing or unmatched values are important, then use itertools.zip_longest()
instead of zip()
from itertools import zip_longest
longest = range(5)
zipped = zip_longest(numbers, letters, longest, fillvalue='?')
list(zipped)
[(1, 'a', 0), (2, 'b', 1), (3, 'c', 2), ('?', '?', 3), ('?', '?', 4)]
Loop Over Multiple Iterables
Looping over multiple iterables is one of the most common use cases for Pythonโs zip()
function
Traverse lists in parallel
letters
['a', 'b', 'c']
numbers
[1, 2, 3]
for l,n in zip(letters, numbers):
print(f'letter: {l}')
print(f'number: {n} \n')
letter: a
number: 1
letter: b
number: 2
letter: c
number: 3
Traverse dictionaries in parallel
dict_one = {'name': 'John', 'last_name': 'Doe', 'job': 'Python Consultant'}
dict_two = {'name': 'Jane', 'last_name': 'Doe', 'job': 'Community Manager'}
for (k1, v1), (k2, v2) in zip(dict_one.items(), dict_two.items()):
print(k1, '->', v1)
print(k2, '->', v2, '\n')
name -> John
name -> Jane
last_name -> Doe
last_name -> Doe
job -> Python Consultant
job -> Community Manager
Unzip a sequence
zip(*zipped)
numbers
[1, 2, 3]
letters
['a', 'b', 'c']
zipped = zip(numbers, letters)
zipped_list = list(zipped)
zipped_list
[(1, 'a'), (2, 'b'), (3, 'c')]
We have a list of tuples and want to separate the elements of each tuple into independent sequences. To do this, we can use zip()
along with the unpacking operator *
,
list(zip(*zipped_list))
[(1, 2, 3), ('a', 'b', 'c')]
Sorting in parallel
Combine two lists and sort them at the same time.
numbers = [2, 4, 3, 1]
letters = ['b', 'a', 'd', 'c']
data1 = list(zip(numbers, letters))
data1
[(2, 'b'), (4, 'a'), (3, 'd'), (1, 'c')]
data1.sort() # sort by numbers
data1
[(1, 'c'), (2, 'b'), (3, 'd'), (4, 'a')]
data2 = list(zip(letters, numbers))
data2
[('b', 2), ('a', 4), ('d', 3), ('c', 1)]
data2.sort() # sort by letters
data2
[('a', 4), ('b', 2), ('c', 1), ('d', 3)]
Use sorted()
and zip()
together to achieve a similar result
data = sorted(zip(letters, numbers))
data
[('a', 4), ('b', 2), ('c', 1), ('d', 3)]
Calculating in pairs
total_sales = [52000.00, 51000.00, 48000.00]
prod_cost = [46800.00, 45900.00, 43200.00]
for sales, costs in zip(total_sales, prod_cost):
profit = sales - costs
print(f'Profit: {profit}')
Profit: 5200.0
Profit: 5100.0
Profit: 4800.0
Building Dictionaries
fields = ['name', 'last_name', 'age', 'job']
values = ['John', 'Doe', '45', 'Python Developer']
a_dict = dict(zip(fields, values))
a_dict
{'name': 'John', 'last_name': 'Doe', 'age': '45', 'job': 'Python Developer'}
Update an existing dictionary by combining zip()
with dict.update()
.
new_job = ['Python Consultant']
field = ['job']
a_dict.update(zip(field, new_job))
a_dict
{'name': 'John', 'last_name': 'Doe', 'age': '45', 'job': 'Python Consultant'}