enumerate と zip を使おう
ループ処理では、インデックスと要素を同時に取得したい場合や、複数のリストを同時に処理したい場合があります。enumerate() 関数と zip() 関数を使えば、これらの処理を簡潔に書くことができます。このレッスンでは、これらの便利な組み込み関数の使い方を学びます。
enumerate() 関数とは
enumerate() 関数は、リストなどをループする際に、インデックス(順番を表す番号)と要素を同時に取得できる組み込み関数です。
まずは簡単な例を見てみましょう。
fruits = ["りんご", "バナナ", "オレンジ"] for index, fruit in enumerate(fruits): print(index, fruit) # => 0 りんご # => 1 バナナ # => 2 オレンジ
このように、enumerate() を使うと、ループの中でインデックスと要素の両方を簡単に取得できます。
enumerate() を使わない場合との比較
enumerate() を使わずにインデックスを取得するには、range() と len() を組み合わせる方法があります。
fruits = ["りんご", "バナナ", "オレンジ"] for i in range(len(fruits)): print(i, fruits[i]) # => 0 りんご # => 1 バナナ # => 2 オレンジ
この方法でも同じ結果が得られますが、fruits[i] のように毎回インデックスでアクセスする必要があり、コードが冗長になります。enumerate() を使えば、より簡潔で読みやすいコードになります。
開始番号を指定する
enumerate() はデフォルトでは 0 から番号が始まりますが、start 引数を使って開始番号を変更できます。
fruits = ["りんご", "バナナ", "オレンジ"] for index, fruit in enumerate(fruits, start=1): print(index, fruit) # => 1 りんご # => 2 バナナ # => 3 オレンジ
例えば、ユーザーに表示する順位やランキングなど、1 から始まる番号を付けたい場合に便利です。
scores = [95, 88, 72] for rank, score in enumerate(scores, start=1): print(f"{rank}位: {score}点") # => 1位: 95点 # => 2位: 88点 # => 3位: 72点
zip() 関数とは
zip() 関数は、複数のリストなどを同時にループ処理できる組み込み関数です。
まずは簡単な例を見てみましょう。
names = ["太郎", "花子", "次郎"] ages = [25, 30, 22] for name, age in zip(names, ages): print(name, age) # => 太郎 25 # => 花子 30 # => 次郎 22
zip() は、各リストから同じ位置の要素を組み合わせて返します。for name, age in zip(...) のように、カンマ区切りで複数の変数に受け取ることができます。
zip() を使わない場合との比較
zip() を使わずに複数のリストを同時にループするには、インデックスを使う方法があります。
names = ["太郎", "花子", "次郎"] ages = [25, 30, 22] for i in range(len(names)): print(names[i], ages[i]) # => 太郎 25 # => 花子 30 # => 次郎 22
この方法でも動作しますが、zip() を使った方がコードが簡潔で意図も明確になります。
3つ以上のリストを組み合わせる
zip() は 2 つだけでなく、3 つ以上のリストも同時に処理できます。
names = ["太郎", "花子", "次郎"] ages = [25, 30, 22] cities = ["東京", "大阪", "福岡"] for name, age, city in zip(names, ages, cities): print(f"{name}さん ({age}歳) - {city}") # => 太郎さん (25歳) - 東京 # => 花子さん (30歳) - 大阪 # => 次郎さん (22歳) - 福岡
zip() で長さが異なるリストを扱う場合
zip() で長さが異なるリストを組み合わせると、最も短いリストの長さに合わせて処理が終了します。
names = ["太郎", "花子", "次郎", "四郎"] ages = [25, 30] for name, age in zip(names, ages): print(name, age) # => 太郎 25 # => 花子 30
上の例では、ages が 2 つの要素しかないため、ループは 2 回で終了し、「次郎」と「四郎」は処理されません。
リストの長さが同じであることを期待する場合は、事前に長さを確認するか、長さが揃っていることを前提としたコードを書くようにしましょう。
まとめ
enumerate()はインデックスと要素を同時に取得できるenumerate(リスト, start=1)のように開始番号を指定できるzip()は複数のリストを同時にループ処理できるzip()の長さは最短のリストに合わせられる
演習に挑戦