Juha-Matti Santala
Community Builder. Dreamer. Adventurer.

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.)