Pythonにおけるzip
を用いたfor
文の使い方について解説します。
Contents
for
文におけるzip
の基本的な使い方
Pythonの繰り返し処理にはfor
文を使用します。for
文の基本については「for文の基本的な使い方」を参照してください。
Pythonのfor
文では、リストや辞書などのイテラブルなオブジェクトを処理します。複数のオブジェクトを同時に処理するにはzip
が便利です。
この記事では、zip
を用いたfor
文の使い方について紹介します。
zip
の基本的な使い方
以降ではリストを対象としてzip
の基本的な使い方を紹介します。以降の例ではリストを使用しましたが、他のイテラブルなオブジェクトにも適用可能です。
zip
で複数リストをまとめてfor
文で実行する方法
以下にzip
を使ったfor
文の例を示します。
data1 = [10, 20, 30, 40, 50] data2 = ["A", "B", "C", "D", "E"] # zipで複数リストをまとめて処理する for dt1, dt2 in zip(data1, data2): print(f"dt1: {dt1}, dt2: {dt2}")
【実行結果】 dt1: 10, dt2: A dt1: 20, dt2: B dt1: 30, dt2: C dt1: 40, dt2: D dt1: 50, dt2: E
zip(data1, data2)
のように複数リストを渡してfor
文で使用します。各ループで、data1
の要素がdt1
に、data2
の要素がdt2
に順に格納されます。
タプル(tuple
)で取得してfor
文を実行する方法
zip
を使うとデータはタプルとして取得されます。for
文で1つの変数に受け取るとタプルとして扱えます。
data1 = [10, 20, 30, 40, 50] data2 = ["A", "B", "C", "D", "E"] # zipで複数リストをまとめて処理する (タプルで取得する) for tpl in zip(data1, data2): print(f"dt1: {tpl[0]}, dt2: {tpl[1]}")
【実行結果】 dt1: 10, dt2: A dt1: 20, dt2: B dt1: 30, dt2: C dt1: 40, dt2: D dt1: 50, dt2: E
上記例では、タプルの0番目がdata1
、1番目がdata2
の値です。
要素数が異なる場合の処理
ここまでzip
の使い方を紹介しましたが、要素数が異なる場合の処理についても説明します。
zip
は少ない要素数のリストにあわせて処理される
zip
では、要素数が異なるリストを扱う場合、少ない方にあわせて処理されて、多い方の残りは無視されます。
以下のようにdata1
の方がdata2
よりも要素が多い場合の例で見てみましょう。
data1 = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100] data2 = ["A", "B", "C", "D", "E"] # 要素の長さが異なる場合(少ない要素数にあわせて実行される) for dt1, dt2 in zip(data1, data2): print(f"dt1: {dt1}, dt2: {dt2}")
【実行結果】 dt1: 10, dt2: A dt1: 20, dt2: B dt1: 30, dt2: C dt1: 40, dt2: D dt1: 50, dt2: E
上記ような場合、要素数の少ないdata2
の要素数にあわせてfor
文が実行されるのでdata1
のデータのうち「60, 70, 80, 90, 100
」は無視されます。
要素数が多い方にあわせて足りない部分を補完して処理する方法(itertools.zip_longest
)
上記までで紹介した通り、zip
では要素の少ない方にあわせて処理されるため、要素数が多い方の残りの部分は無視されてしまいました。しかし、要素数の多い方のデータもすべて含めて扱いたい場合もあります。
このように要素数が多い方のリストに合わせて処理をしたい場合には、itertools
パッケージのzip_longest
を使用することができます。itertools
は、イテレーションに関する様々なユーティリティを提供し、かつ効率のよく処理をしてくれるライブラリです。
以下の例でzip_longest
の使い方を見てみましょう。
import itertools data1 = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100] data2 = ["A", "B", "C", "D", "E"] # itertools.zip_longestを用いて、不足分をNoneで補完する for dt1, dt2 in itertools.zip_longest(data1, data2): print(f"dt1: {dt1}, dt2: {dt2}")
【実行結果】 dt1: 10, dt2: A dt1: 20, dt2: B dt1: 30, dt2: C dt1: 40, dt2: D dt1: 50, dt2: E dt1: 60, dt2: None dt1: 70, dt2: None dt1: 80, dt2: None dt1: 90, dt2: None dt1: 100, dt2: None
zip_longest
を使用するには、itertools
をインポートが必要です。デフォルトでは、足りない部分はNone
で補完されます。
itertools.zip_logest
で任意の指定値で補完したい場合(fillvalue
)
zip_longest
は、デフォルトでは少ない方の要素をNone
で補完しますが、fillvalue
引数で任意の値を指定できます。
import itertools data1 = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100] data2 = ["A", "B", "C", "D", "E"] # itertools.zip_longestで、補完する値を指定する for dt1, dt2 in itertools.zip_longest(data1, data2, fillvalue="Z"): print(f"dt1: {dt1}, dt2: {dt2}")
【実行結果】 dt1: 10, dt2: A dt1: 20, dt2: B dt1: 30, dt2: C dt1: 40, dt2: D dt1: 50, dt2: E dt1: 60, dt2: Z dt1: 70, dt2: Z dt1: 80, dt2: Z dt1: 90, dt2: Z dt1: 100, dt2: Z
上記例では、補完にfillvalue="Z"
を指定しているため、data2
のリストで不足する部分には、Z
が補完されていることが分かります。
まとめ
Pythonにおけるzip
を用いたfor
文の使い方について解説しました。
zip
は複数のイテラブルなオブジェクトをfor
文で同時に処理するために使用します。例で紹介したリスト以外のイテラブルにも使えるので、柔軟に利用できます。
zip
では、値を直接取得する方法とタプルとして取得する方法があります。また、zip
は要素数が異なる場合は少ない方にあわせて処理されますが、itertools
のzip_longest
を使うことで不足する部分を補完して処理することもできます。
for
文での処理では、zip
は非常によく使う方法ですので、うまく使いこなせるようになってもらいたいと思います。