zip関数 複数のリストを同時にループで処理する

zip関数

複数のリストを同時にループで回したい場合があると思いますが、そんな場合、zip関数を使用します。引数にリストを指定すると、反復子が返されます。サンプルを見てみましょう。

data1 = [1, 2, 3, 4, 5]
data2 = ['a', 'b', 'c', 'd', 'd']

for x, y in zip(data1, data2):
    print(x, y)

特に説明は不要かと思いますが、実行してみるとdata1、data2のリストの内容が順に出力されます。リストでなくとも、シーケンシャルなオブジェクトであれば何でも構いません。

さて、このzip関数ですが、2つどころか3つでも4つでも可能です。3つの場合も同様に、以下のように記述できます。

# 3つでも可能
data1 = [1, 2, 3, 4, 5]
data2 = ['a', 'b', 'c', 'd', 'd']
data3 = ['e', 'f', 'g', 'h', 'i']

for x, y, z in zip(data1, data2, data3):
    print(x, y, z)

長さの異なるリスト

一見同じ長さでなければならないように見えますが、そこはちゃんと空気を読んで、一番短いリストに合わせて処理をしてくれます。

data1 = [1, 2, 3]
data2 = [1, 2, 3, 4]
data3 = [1, 2, 3, 4, 5]

for x, y, z in zip(data1, data2, data3):
    print(x, y, z) # 3回出力される

例えば上のサンプルの場合、ループ中の処理回数は一番短いdata1に合わせて3回処理されます。(本稿の主題からはずれますが、)長い方と合わせるたい場合は以下のように適当な値で埋めればよいでしょう。

data1 + [None]*(10 - len(data1)) # 長さを10にして、足りない部分はNoneで埋める

ループインデックスの取得 enumerateと組み合わせる

さて、ループインデックスを取得する場合はenumerateを使用しますが、この場合ちょっと工夫が必要となります。以下サンプルのとおり、カッコが必要となるので注意してください。

# enumerateと組み合わせる場合
for idx, (x, y, z) in enumerate(zip(data1, data2, data3)):
    # カッコが必要。
    print(idx, x, y, z)