enumerate でインデックス付きループ

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

enumerate でインデックス付きループ とは

enumerate を使って、リストの要素と一緒にインデックス番号を取り出すパターンを学ぶ。本レッスンでは、enumerate でインデックス付きループ の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

enumerate でインデックス付きループ

for でリストを回しながら「いま何番目か」を知りたい場面はよくあります。素朴に書くと range(len(items)) でインデックスを回し、items[i] で値を取り出す形になりますが、Python ではもっと綺麗な書き方があります。それが組み込み関数 enumerate です。本レッスンでは、enumerate の使い方とインデックス付きループの定番パターンを学びます。

enumerate は「列挙する」という意味の英語で、要素と番号をペアにして取り出してくれます。

enumerate の基本

enumerate(iterable, start=0) は、(インデックス, 要素) のタプルを返すイテレータです。for のターゲットを 2 つに分解すれば、インデックスと要素を別々の変数で受け取れます。

Python

items = ['apple', 'banana', 'cherry'] for i, v in enumerate(items): print(i, v) # 0 apple # 1 banana # 2 cherry

start 引数を渡すと開始インデックスを変えられます。enumerate(items, start=1) とすれば 1, 2, 3 から番号が振られます。これは「1 番から表示したい」「ヘッダー行を 0 とは別の番号で扱いたい」といったときに便利です。

for i in range(len(items)) より、for i, v in enumerate(items) の方が読みやすく、間違いも減ります。

インデックス付きで整形する

本レッスンの課題は、文字列のリストを受け取り、'1: apple' のように 1 始まりの番号 を付けた新しい文字列リストを返すことです。enumerate(items, start=1) を使えば素直に書けます。

Python

def numbered_list(items): result = [] for i, v in enumerate(items, start=1): result.append(f'{i}: {v}') return result

上のコードは items = ['apple', 'banana'] のとき ['1: apple', '2: banana'] を返します。f'{i}: {v}':f-string の書式指定 ではなく、出力する文字列の中の「: 」というセパレータです。慣れないうちは違和感がありますが、Python の f-string は単に文字列の途中で {} を埋め込んでいるだけなので、: も普通の文字として扱えます。

インデックスを使いたいときの第一選択肢は enumerate と覚えておきましょう。

動きを追ってみる

items = ['a', 'b', 'c'] のときの遷移は次の通りです。

diagram (will load when visible)

enumerate は要求されるたびに次のペアを 1 つ作るだけのイテレータです。一気に全部展開しないので、巨大なリストでもメモリ効率良く回せます。

よくある間違い

enumerate でつまずきやすいポイントは次の通りです。

  • for i in enumerate(items) と書き、タプルのまま使ってしまう
  • start を渡し忘れて 0 始まりになる
  • enumerate(items, 1) を書き間違えて enumerate(items)[1] にする
  • f-string の {i:v} のように : を書式指定子と混同する
  • インデックスと値の順番を逆にしてしまう

Python

# NG: タプルのまま受け取って index と value を分離できていない for t in enumerate(items): print(t) # (0, 'apple') のように表示される

for i, v in enumerate(items): のように アンパック すれば、i がインデックス、v が要素になります。順番を逆に書くと意味が変わるので、必ず i, v の順で書く習慣をつけましょう。タプルが何かまだ曖昧な人は、enumerate を学ぶこのタイミングでサッと復習しておくと、後の章でも応用が効きます。

番号と内容を一緒に出すときは、enumerate + f-string が定番の組み合わせです。

やってみよう

このレッスンでは、文字列のリスト items を受け取り、'1: apple' のように 1 始まりの番号を付けた文字列リストを返す関数 numbered_list(items) を実装します。空リストを受け取ったときは空リストを返してください。enumerate(items, start=1) を使うと素直に書けます。f'{i}: {v}' の書き方も合わせて覚えましょう。

余裕があれば、for i in range(len(items)) で書いた場合と比較し、enumerate の方が読みやすいことを実感してください。

よくある質問

Q. enumerate と range(len()) はどっちが良いですか?

A. enumerate(items) が推奨です。for i, v in enumerate(items): のように書けばインデックスと値が同時に取れ、リストの中身を 2 回参照する無駄も省けます。range(len(items)) はインデックスだけ欲しい場面に限定して使うと良いです。

Q. 開始番号を 1 から始められますか?

A. enumerate(items, start=1) と書けば 1 から始まります。ユーザー向けに 1 始まりで表示したい一覧(順位付き、行番号付き)で便利です。デフォルトの 0 始まりとどちらを使うかは仕様に合わせて決めてください。

Q. 辞書を enumerate で回せますか?

A. 回せますがデフォルトではキーだけ列挙されます。値も欲しい場合は enumerate(d.items()) を使い、for i, (k, v) in enumerate(d.items()): のように書きます。タプルアンパックの括弧を忘れると SyntaxError になるので注意してください。

次のレッスン

次は zip で 2 つのリストをペアにする で、enumerate を使って、リストの要素と一緒にインデックス番号を取り出すパターンを学ぶ を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. enumerate で index の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. enumerate で index とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. enumerate を使ってインデックスと値を取り出すこと
  2. 番号は 1 から始めること
  3. f-string で 'index: value' の形に整形すること

入出力例

test-cases.txt

numbered_list(["apple","banana","cherry"])["1: apple","2: banana","3: cherry"] numbered_list(["hello"])["1: hello"] numbered_list([])[] numbered_list(["x","y"])["1: x","2: y"] numbered_list(["a1","b2"])["1: a1","2: b2"]

ヒント

main.py
main.py
学習モード

メモ

enumerate でインデックス付きループ

⌘S で保存