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つ以上のデータでも使える
  • 無限イテレータと組むと止まらない
  • データの欠けを見逃したくないときに使う

あわせて読みたい

対面・無料|東京・永田町で毎週開催

1回の参加で、プログラミングの構造がわかる

ゼロからはじめるPython入門講座

8年間・累計600回開催/これまで全国で2万人以上が参加

「やはり対面で聞けるのはとても気づきがあり、価値があると思います」

参加者の声

  • 本当に初心者からの講座です。プログラミングに触ったことがなくて大丈夫です
  • 対面だから、その場で聞けます。つまずいた所を持ち帰らずに解決できます
  • 講座は1時間。そのあとも残って学習を続けられ、講師にも質問できます
  • 独学で挫折した方も。糸口が見つかって、講座のあと会員になる方が多くいます

無料で参加する|開催日程を見る

参加費は無料です