リストや文字列をfor
で回すときに「今のインデックス番号も欲しい」と思ったことはありませんか。
Pythonではenumerate
を使うだけで、面倒なカウンタ管理なしにインデックスと要素を同時に取得できます。
ゼロから使い方と注意点を整理し、すぐに使えるサンプルも紹介します。
enumerateとは?forループでインデックスと要素を同時取得
enumerate(イテラブル, start=0)
は、(インデックス, 要素)のペアを順に返すイテレータです。
インデックスはデフォルトで0から始まり、start
引数で任意の開始番号に変更できます。
戻り値は各要素の位置と値の組なので、ループ内でカウンタを自分で増やす必要がなくなります。
挙動を視覚的に確認
# enumerateが返すものは(インデックス, 要素)のタプル
items = ["a", "b", "c"]
# リスト化して中身を確認
print(list(enumerate(items))) # [(0, 'a'), (1, 'b'), (2, 'c')]
# ふつうはforでアンパックして使います
for i, x in enumerate(items):
print(i, x)
[(0, 'a'), (1, 'b'), (2, 'c')]
0 a
1 b
2 c
方法の比較(ざっくり)
読みやすさとミスの少なさでenumerate
が基本的に優れます。
方法 | 書き方の例 | 特徴 | おすすめ |
---|---|---|---|
enumerate | for i, x in enumerate(seq): | カウンタ不要・読みやすい | 高 |
range(len) | for i in range(len(seq)): x = seq[i] | インデックスのみ必要なときに限り有効 | 中 |
手動カウンタ | i = 0; for x in seq: …; i += 1 | バグの温床・冗長 | 低 |
Python enumerateの使い方(基本)
リストをforで回して(インデックス, 要素)を取り出す
もっとも基本的な使い方は、インデックスと要素を同時に受け取って処理する形です。
# 例: フルーツ一覧に順番付きでアクセス
fruits = ["apple", "banana", "cherry"]
for index, fruit in enumerate(fruits):
# indexは0から始まる
print(f"{index}: {fruit}")
0: apple
1: banana
2: cherry
start引数で開始番号を1からにする
人間に見せる番号は1始まりが自然です。
その場合はstart=1
を指定します。
# 行番号のように1始まりにしたい場合
languages = ["Python", "JavaScript", "Go"]
for no, lang in enumerate(languages, start=1):
print(f"{no}. {lang}")
1. Python
2. JavaScript
3. Go
startは0や1に限らず任意の整数が使えます(例: ページングの続き番号など)。
タプルのアンパックで変数名をわかりやすくする
enumerate
が返す各要素は(index, value)という2要素タプルです。
タプルのアンパックで意味のある変数名を付けると読みやすくなります。
letters = ["x", "y", "z"]
# アンパックを使わない(読みにくい例)
for pair in enumerate(letters):
# pairは(インデックス, 値)のタプル
print(pair)
# アンパックを使う(推奨)
for idx, ch in enumerate(letters):
print(f"idx={idx}, ch={ch}")
(0, 'x')
(1, 'y')
(2, 'z')
idx=0, ch=x
idx=1, ch=y
idx=2, ch=z
よくある間違いと注意点
手動でカウンタを増やさない(enumerateを使う)
手動でi += 1
する方法はバグのもとです。
常にenumerate
を優先しましょう。
items = ["A", "B", "C"]
# NG例: 手動カウンタ
i = 0
for x in items:
print(i, x)
i += 1
# OK例: enumerate
for i, x in enumerate(items):
print(i, x)
0 A
1 B
2 C
0 A
1 B
2 C
不要な値は_で受ける(インデックスだけ/要素だけ)
どちらか一方だけが必要なときは、使わないほうを_
(ダミー変数)で受けると意図が明確です。
colors = ["red", "green", "blue"]
# インデックスだけ使う
for i, _ in enumerate(colors):
print(i)
# 要素だけ使う(番号は使わない)
for _, color in enumerate(colors, start=1):
print(color)
0
1
2
red
green
blue
補足として、純粋にインデックスだけが必要ならfor i in range(len(colors)):
のほうが簡潔な場合もあります。
ただし要素も使うならenumerate
が最適です。
イテラブルなら使える(リスト/文字列)
enumerate
はリスト・タプル・文字列などのイテラブル全般に使えます。
文字列を回すと1文字ずつ取り出せます。
text = "ABC"
for i, ch in enumerate(text):
print(i, ch)
0 A
1 B
2 C
注意点として、集合(set
)は順序が安定しないため、インデックスに意味を持たせたい用途には不向きです。
辞書はキーの順序が挿入順になりますが、enumerate(d)
はキーのみを返すため、キーと値を扱いたい場合はfor i, (k, v) in enumerate(d.items()):
のように書きます。
初心者向けミニサンプル
行番号付きでリストを表示(start=1)
1行目から番号を振って表形式で表示してみます。
整列のために桁幅指定({no:>2}
)を使っています。
files = ["report.pdf", "memo.txt", "data.csv", "image.png"]
# 1始まりで、番号の桁を2にそろえる
for no, name in enumerate(files, start=1):
print(f"{no:>2}: {name}")
1: report.pdf
2: memo.txt
3: data.csv
4: image.png
文字列の各文字に番号を付ける
テキストにインデックスを振ってデバッグすると、スペースや記号の位置確認に便利です。
s = "Python 3.12"
# 1始まりにして、見やすく整形
for i, ch in enumerate(s, start=1):
# repr(ch)で空白や改行なども可視化できる
print(f"{i:>2}: {repr(ch)}")
1: 'Python 3.12'[0:1] # ← この行のような表記にならないため修正します
おっと、上の出力例の表現は分かりづらいので、素直に文字だけを可視化します。
s = "Python 3.12"
for i, ch in enumerate(s, start=1):
# 空白や記号も見えるようにreprを使う
print(f"{i:>2}: {repr(ch)}")
1: 'P'
2: 'y'
3: 't'
4: 'h'
5: 'o'
6: 'n'
7: ' '
8: '3'
9: '.'
10: '1'
11: '2'
reprを使うと空白が' '
のように見えるため、目視の確認に便利です。
まとめ
enumerateは「インデックスと要素を同時に得る」というニーズに対するPythonの標準解です。
デフォルトは0始まりですがstart
で1始まりにもでき、タプルのアンパックで読みやすい変数名を使えます。
カウンタの手動管理は避け、不要な値は_
で明確に捨てると、コードの意図がはっきりします。
リストや文字列などのイテラブル全般で使えるため、まずは日常のfor
処理をenumerate
に置き換えて、短く・安全で・読みやすいコードにしていきましょう。