enumerate() の概要(要素とインデックスを同時に扱う)
enumerate() は、イテラブル(リスト、タプル、文字列など)をループするときに「要素の値」と「インデックス番号」を同時に受け取れるようにする組み込み関数です。コードが短く読みやすくなり、range(len(…)) のような手動のインデックス管理を避けられます。
基本の使い方とシグネチャ(ここが重要)
基本形と戻り値
書式は enumerate(iterable, start=0)。start はインデックスの開始値(省略時は 0)で、返されるのは (index, value) のペアの連続です。for で受け取るときは「for i, x in enumerate(…):」の形が定番です。
fruits = ["apple", "banana", "orange"]
for i, fruit in enumerate(fruits):
print(i, fruit)
# 0 apple
# 1 banana
# 2 orange
Pythonインデックスの開始値を変える(1始まりなど)
ユーザー表示などで「1番、2番…」にしたいなら、start=1 を指定します。内部ロジックは 0始まり、UIは 1始まりにするなどの使い分けができます。
for i, fruit in enumerate(fruits, start=1):
print(i, fruit)
# 1 apple
# 2 banana
# 3 orange
Python実用的なパターン(インデックス管理の置き換えと文字列)
range(len(…)) の置き換えで読みやすく
インデックスが必要でも enumerate を使えば、要素参照のために毎回リストへ戻る必要がありません。可読性が高く、バグ(±1のズレ)も避けやすいです。
# 旧来の書き方
for i in range(len(fruits)):
print(i, fruits[i])
# 推奨(読みやすい)
for i, fruit in enumerate(fruits):
print(i, fruit)
Python文字列もそのまま使える
文字列は1文字ずつのイテラブルなので、位置と文字を同時に扱えます。
text = "Python"
for i, ch in enumerate(text):
print(i, ch)
Python深掘りポイント(読みやすさ・パフォーマンス・使い分け)
読みやすさの軸
- 「インデックスも要素も必要」なら enumerate、一方で「複数コレクションを同位置で処理」なら zip が適切です。range(len(…)) は、インデックス以外の情報がないとき以外は避けると読みやすく保てます。
イテラブルとしての軽さ
enumerate はイテレータを返し、値を必要時に順次生成します。巨大なコレクションでも余計な中間リストを作らずに扱えるため、基本的にメモリ効率が良いままインデックスを付与できます。
例題で身につける(定番から一歩先まで)
例題1:番号付きメニューの表示(start=1)
items = ["コーヒー", "紅茶", "水"]
for i, item in enumerate(items, start=1):
print(f"{i}. {item}")
Python例題2:条件に合う最初の位置を特定
scores = [70, 85, 90, 60]
pos = None
for i, s in enumerate(scores):
if s >= 90:
pos = i
break
print(pos) # 2(0始まり)
Python例題3:インデックスと値を同時に加工
names = ["taro", "hanako", "jiro"]
labels = [f"{i+1}-{n.upper()}" for i, n in enumerate(names)]
print(labels) # ['1-TARO', '2-HANAKO', '3-JIRO']
Python例題4:複数列と組み合わせ(zip と比較)
names = ["太郎", "花子", "次郎"]
points = [92, 88, 75]
# インデックスも欲しいなら enumerate + zip
for i, (name, point) in enumerate(zip(names, points), start=1):
print(f"{i}: {name} {point}")
Pythonよくある落とし穴と対策(重要ポイント)
インデックスの開始値の意図を合わせる
内部ロジックは 0始まり、表示は 1始まりにするなど、start の使い分けを明確に。混在するとバグの温床になるため、関数の入出力でどちらを採用するか統一します。
コレクションを変更しながら回さない
ループ中に元のリストを追加・削除すると、インデックスと実体がずれて予期せぬ挙動になります。必要なら「コピーを回す」か「結果用リストへ書き出す」設計にします。
不要な list(…) 化を避ける
enumerate はそのまま for で扱うのが基本です。検証やデバッグ目的以外で、即座に list(enumerate(…)) として展開すると無駄が増えます。
まとめ
enumerate() は、要素の値とインデックスを同時に扱えるため、range(len(…)) を置き換えてコードを短く、正確にします。シグネチャは enumerate(iterable, start=0)、表示用途などでは start を活用。巨大データでもイテレータとして軽く動き、文字列にもそのまま使えます。zip との使い分け、インデックス開始の統一、コレクション変更の回避を意識すれば、初心者でも読みやすく堅牢なループが書けます。
