はじめに
Pythonのzip()関数を使うと、複数のイテラブル(リスト、タプル、辞書、集合のように繰り返し可能なオブジェクト)から要素を取り出し、対応する要素をまとめることができます。
zip()関数の使用例
例えば、キーと値が別々のイテラブルであっても、dict()関数とzip()関数を使うことで簡単に辞書を生成することができます。
zip_dict.py
drink = 'milk', 'tea', 'coffee', 'juice' # キーのイテラブル
price = 160, 210, 150, 250 # 値のイテラブル
dict(zip(drink, price))
# {'coffee': 150, 'juice': 240, 'tea': 220}
zip()関数を使用する場合の注意点
異なる長さの複数のイテラブルにzip()関数を使用すると、zip()関数は短いほうのイテラブルに合わせて処理を終了してしまうので、長いほうのイテラブルに処理されなかった要素が存在することを警告してくれません。
どうすればいいのか?
Python 3.10から、zip()関数にstrictオプションが追加されたので、複数のイテラブルの長さが異なる場合は、ValueErrorを発生させるようにしましょう。
zip_strict.py
drink = 'coffee', 'juice', 'tea', 'milk'
price = 150, 240, 220
for x, y in zip(drink, price, strict=True):
print(x, y)
# この例では、イテラブルの長さが異なるので次のエラーが発生します。
ValueError: zip() argument 2 is shorter than argument 1
zip_longest()を使う
zip()と似たzip_longest()という関数を使うこともできます。zip_longest()はzip()と異なり、長いほうのイテラブルに合わせてイテレータを作成します。 短いほうのイテラブルで、長いほうのイテラブルの長さを超えた場合の要素はデフォルトではNoneを返します。zip_longest()を使うにはitertoolsをインポートする必要があります。
zip_longest1.py
import itertools
for x, y in itertools.zip_longest('aiu', '12'):
print(x, y)
# 出力結果
a 1
i 2
u None
None以外の値を返したい場合は、fillvalueという引数で指定します。
zip_longest2.py
import itertools
for x, y in itertools.zip_longest('aiu', '12', fillvalue='N/A'):
print(x, y)
# 出力結果
a 1
i 2
u N/A