Python itertools.zip_longest()とは?長さの違うデータを揃える方法
Pythonのitertools.zip_longest()は、長さの違うデータを最長に合わせて組にする関数です。
組み込みのzip()が短いほうで打ち切るのに対し、足りない部分を埋めて最後まで回します。
itertools.zip_longest()の基本的な使い方
from itertools import zip_longest
print(list(zip_longest("ABC", "12")))
print(list(zip("ABC", "12")))
実行結果:
[('A', '1'), ('B', '2'), ('C', None)]
[('A', '1'), ('B', '2')]
zip()ではCが消えました。zip_longest()なら足りないところがNoneで埋まり、3件すべて残ります。
fillvalueで埋める値を変える
from itertools import zip_longest
print(list(zip_longest("ABC", "12", fillvalue="-")))
print(list(zip_longest([1, 2, 3], [10, 20], fillvalue=0)))
実行結果:
[('A', '1'), ('B', '2'), ('C', '-')]
[(1, 10), (2, 20), (3, 0)]
数値の計算に使うならfillvalue=0、表示用ならfillvalue=""が便利です。Noneのまま計算するとTypeErrorになるので、用途に合わせて指定してください。
3つ以上でも使える
from itertools import zip_longest
print(list(zip_longest("AB", "123", "xyzw", fillvalue="*")))
実行結果:
[('A', '1', 'x'), ('B', '2', 'y'), ('*', '3', 'z'), ('*', '*', 'w')]
いちばん長いもの(4件)に合わせて4組できました。それぞれ足りない部分が*で埋まっています。
fillvalueは全体で共通
列ごとに違う埋め値を指定することはできません。fillvalueは1つだけです。
列ごとに変えたいときは、あらかじめ各リストの長さをそろえるか、後から書き換えてください。
実践例|表の行の欠けを埋める
from itertools import zip_longest
head = ["名前", "年齢", "都市"]
row = ["佐藤", "28"]
print(dict(zip_longest(head, row, fillvalue="")))
実行結果:
{'名前': '佐藤', '年齢': '28', '都市': ''}
列数が足りないCSVの行を、辞書にするときに安全に処理できます。zip()だと都市のキー自体が消えてしまい、あとでKeyErrorの原因になります。
実践例|リストをn個ずつに分ける
有名なイディオムです。
from itertools import zip_longest
data = [1, 2, 3, 4, 5, 6, 7]
print(list(zip_longest(*[iter(data)] * 3, fillvalue=None)))
実行結果:
[(1, 2, 3), (4, 5, 6), (7, None, None)]
3個ずつのまとまりになりました。同じイテレータを3つ並べてzipすると、1つのデータから順に3個ずつ取り出されるという仕組みです。
ただし読みにくいコードでもあります。Python 3.12以降ならitertools.batched()があり、そちらのほうが素直です。
無限イテレータと組むと止まらない
from itertools import zip_longest, count
zip_longest(count(), "AB") # ← list()にすると止まらない
zip()は短いほうで止まるため無限イテレータと組んでも安全ですが、zip_longest()は長いほうに合わせるため終わりません。
from itertools import count
print(list(zip(count(), "AB")))
実行結果:
[(0, 'A'), (1, 'B')]
無限イテレータを混ぜるならzip()を使ってください。
zip()とzip_longest()の使い分け
| 項目 | zip() |
zip_longest() |
|---|---|---|
| 終わるタイミング | 最短に合わせる | 最長に合わせる |
| 足りない部分 | 切り捨てる | fillvalueで埋める |
| import | 不要(組み込み) | itertoolsから |
| 無限イテレータ | 安全 | 止まらない |
| 使いどころ | 長さが同じ前提 | 欠けを見逃したくない |
データが欠けていることに気づきたいならzip_longest()です。zip()は黙って切り捨てるため、バグの発見が遅れます。
itertools.zip_longest()のまとめ
zip_longest()は最長に合わせて組にする- 足りない部分は既定で
None。fillvalueで変更できる fillvalueは全体で1つ。列ごとには指定できない- 3つ以上のデータでも使える
- 無限イテレータと組むと止まらない
- データの欠けを見逃したくないときに使う


