Combine iterables with zip
Batteries included is a blog series about the Python Standard Library. Each day, I share insights, ideas and examples for different parts of the library. Blaugust is an annual blogging festival in August where the goal is to write a blog post every day of the month.
If you’re new to Python, either as a new programmer in general or coming from another programming language, a handy Python built-in to learn is zip.
Combine similar iterables
Zip allows you to combine two or more iterables into one with each corresponding item being grouped:
letters = ['A', 'B', 'C', 'D']
numbers = [1, 2, 3, 4]
for letter, number in zip(letters, numbers):
print(f'{letter} and {number}')
# A and 1
# B and 2
# C and 3
# D and 4
An equivalent non-zip solution using indices could look like this:
letters = ['A', 'B', 'C', 'D']
numbers = [1, 2, 3, 4]
for index in range(len(letters)):
letter = letters[index]
number = numbers[index]
print(f'{letter} and {number}')
In my opinion, the first one is more elegant and more pythonic, taking advantage of language’s constructs and built-ins in a way that improves readability.
If your iterables are not of equal length, the zip will ignore all the unpaired ones:
longer = [1, 2, 3, 4, 5, 6, 7]
shorter = [1, 2, 3]
for first, second in zip(longer, shorter):
print(f'{first} and {second}')
# 1 and 1
# 2 and 2
# 3 and 3
If you want to zip in a way that keeps all the items from the longest
iterable, you can use
itertools.zip_longest
which allows defining a fill value for missing items:
from itertools import zip_longest
longer = [1, 2, 3, 4, 5, 6, 7]
shorter = [1, 2, 3]
for first, second in zip_longest(longer, shorter, fillvalue=0):
print(f'{first} and {second}')
# 1 and 1
# 2 and 2
# 3 and 3
# 4 and 0
# 5 and 0
# 6 and 0
# 7 and 0
Transpose a matrix
When working with two-dimensional lists (lists of lists), there often comes a need to transpose the array which means switching columns and rows:
1 2 3
4 5 6
7 8 9
->
1 4 7 (first column of the original)
2 5 8
3 6 9
To achieve this with Python, you can zip the unpacked list:
matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]
transposed = zip(*matrix)
(Note that if you’re dealing with a lot of matrix shaped data, pandas offers good tooling for them.)