記事内にはプロモーションが含まれています

【Python】for文でインデックス付きでループする方法(enumerate関数の使い方)

【Python】for文でインデックス付きでループする方法(enumerate関数の使い方) Python

Pythonでリスト(配列)やタプルなどのデータを扱う際、for文を使って要素を順番に取り出す処理は日常的に行われます。

その中で、

「要素の値だけでなく、今の要素が何番目なのかというインデックスも一緒に取得したい」

という場面に遭遇することは非常に多いです。

他のプログラミング言語、例えばC言語やJavaの経験がある方は、カウンタ変数を自分で用意したり、配列の長さを使ってループさせたりする方法を思い浮かべるかもしれません。

しかし、Pythonにはもっとスマートで可読性の高い「Pythonic(パイソニック)」な書き方が用意されています。

この記事では、Pythonのfor文でインデックス付きでループ処理を行うための基本から応用、そして現場で使われるベストプラクティスまで、最新情報に基づいて解説します。

【本記事の信頼性】
プロフィール
執筆者:マヒロ
  • 執筆者は元エンジニア
  • SES⇒大手の社内SE⇒独立
  • 現在はこじんまりとしたプログラミングスクールを運営
  • モットーは「利他の精神」

Pythonでインデックス付きループを行う基本は「enumerate関数」

Pythonでインデックスと要素を同時に取得したい場合、最も推奨される方法は標準組み込み関数である enumerate(エニュメレート)関数を使うことです。

この関数を使うことで、リストの長さ(len関数)を取得したり、手動でカウンタ変数をインクリメントしたりする手間が省けます。

まずは基本的な使い方と、実務でよく使われる「インデックスの開始番号を変更する方法」について見ていきましょう。

enumerate関数の基本的な使い方

enumerate関数は、第一引数にリストなどのイテラブル(繰り返し可能なオブジェクト)を渡します。
すると、インデックスと要素がペアになったオブジェクトを返します。

for文でこれを受け取る際には、変数を2つ用意してアンパック(展開)するのが一般的です。

以下のサンプルコードは、果物のリストから要素を順番に取り出し、番号を振って表示する例です。

fruits = ["apple", "banana", "cherry"]

# enumerate関数を使ってインデックスと要素を同時に取得
for i, fruit in enumerate(fruits):
    print(f"インデックス: {i}, 値: {fruit}")

実行結果

インデックス: 0, 値: apple
インデックス: 1, 値: banana
インデックス: 2, 値: cherry

ソースコードの解説

for文の in の後ろに enumerate(fruits) を記述しています。

これにより、ループが回るたびに (0, "apple"), (1, "banana") … というペアが取り出されます。

for i, fruit の部分で、ペアの左側(インデックス)を変数 i に、右側(要素)を変数 fruit に代入しています。
Pythonのインデックスは0から始まるため、最初の値は0となります。

このように、非常にシンプルな記述で目的を達成できるのが特徴です。

インデックスの開始番号を1からにする方法

ランキングの表示やログの行番号表示など、インデックスを「0」からではなく「1」から始めたいケースは多々あります。

ループの中で i + 1 のように計算して表示することも可能ですが、enumerate関数の第二引数 start を使う方法がよりスマートです。

fruits = ["apple", "banana", "cherry"]

# 第二引数に「1」を指定して、1からカウントを開始する
for i, fruit in enumerate(fruits, start=1):
    print(f"{i}番目のフルーツは{fruit}です")

実行結果

1番目のフルーツはappleです
2番目のフルーツはbananaです
3番目のフルーツはcherryです

ソースコードの解説

enumerate(fruits, start=1) と記述することで、インデックスの開始値を変更できます。
ここを start=100 とすれば100から始まりますし、任意の整数を指定可能です。

コードを読む人に対しても「ああ、ここは1から番号を振りたいんだな」という意図が明確に伝わるため、可読性の観点からも計算式を書くよりこのオプションを利用することを推奨します。

enumerate関数以外の方法とメリット・デメリット

Pythonでインデックスを取得する方法はenumerateだけではありません。

状況によっては他の方法が採用されることもありますし、古いコードを読む際には知っておく必要があります。

ここでは、range関数を使った従来の方法や、手動でカウンタを管理する方法を紹介し、それぞれのメリットとデメリットを比較します。

range関数とlen関数を組み合わせる方法

C言語やJavaなどのスタイルに慣れている人が書きがちなのが、range()len() を組み合わせる方法です。

リストの長さ分の整数の数列を作り、その数値を使ってリストにアクセスします。

fruits = ["apple", "banana", "cherry"]

# リストの長さ分だけループし、インデックスでアクセスする
for i in range(len(fruits)):
    print(f"インデックス: {i}, 値: {fruits[i]}")

実行結果

インデックス: 0, 値: apple
インデックス: 1, 値: banana
インデックス: 2, 値: cherry

ソースコードの解説

len(fruits) でリストの要素数(3)を取得し、range(3)0, 1, 2 という数値を生成しています。

ループ内で fruits[i] と記述して要素にアクセスしています。

この方法のデメリットは、コードが長くなりがちな点と、リストへのアクセス処理 fruits[i] を都度書く必要がある点です。

ただし、リストの中身を書き換えたい場合(fruits[i] = "new value")などには、この形式が適している場合もあります。

カウンタ変数を手動で管理する方法

for文の外で変数を定義し、ループ内で加算していく方法です。

これはPythonにおいてはあまり推奨されませんが、while文を使う際などには見かけるパターンです。

fruits = ["apple", "banana", "cherry"]

i = 0
for fruit in fruits:
    print(f"インデックス: {i}, 値: {fruit}")
    i += 1  # インデックスを手動で増やす

実行結果

インデックス: 0, 値: apple
インデックス: 1, 値: banana
インデックス: 2, 値: cherry

ソースコードの解説

ループの前に i = 0 を定義し、ループの最後で i += 1 としています。

この書き方の最大のリスクは、インクリメント(i += 1)を書き忘れるとインデックスが変わらない、あるいはwhile文の場合は無限ループに陥る可能性があることです。

特別な理由がない限り、for文においては避けたほうが無難でしょう。

【応用】複数のリストや辞書型でインデックスを取得する

実務では、単一のリストを回すだけではなく、複数のリストを同時に扱ったり、辞書型(ディクショナリ)を扱ったりするケースもあります。

ここでは、zip関数と組み合わせた方法や、辞書型でのインデックス取得方法といった応用テクニックを解説します。

zip関数と組み合わせて複数のリストをループする

「名前のリスト」と「年齢のリスト」のように、関連する2つのリストを同時にループさせつつ、インデックスも欲しい場合は、enumeratezip を組み合わせます。

names = ["Tanaka", "Sato", "Suzuki"]
ages = [25, 30, 28]

# zipでまとめたものをenumerateで囲む
for i, (name, age) in enumerate(zip(names, ages)):
    print(f"ID: {i}, 名前: {name}, 年齢: {age}")

実行結果

ID: 0, 名前: Tanaka, 年齢: 25
ID: 1, 名前: Sato, 年齢: 30
ID: 2, 名前: Suzuki, 年齢: 28

ソースコードの解説

zip(names, ages) によって、名前と年齢がペアになります。
それをさらに enumerate で囲むことで、インデックスが付与されます。

変数を受け取る部分が for i, (name, age) となっている点に注目してください。

i にインデックスが入り、(name, age) の部分でzipされた要素を受け取っています。

括弧をつけることでタプルのアンパックを明示していますが、括弧を省略して for i, name, age と書くとエラーになるケースや意図しない挙動になることがあるため、構造を意識して記述することが大切です。

辞書型(dict)でインデックスとキー・値を取得する

辞書型には順序(Python 3.7以降は挿入順が保持されます)がありますが、リストのようにインデックスで管理されるものではありません。

しかし、何番目に処理されたかを知りたい場合は enumerate を使えます。

user_scores = {"Tanaka": 80, "Sato": 95, "Suzuki": 60}

# 辞書のitems()メソッドをenumerateで囲む
for i, (name, score) in enumerate(user_scores.items()):
    print(f"{i+1}人目: {name}さんは{score}点です")

実行結果

1人目: Tanakaさんは80点です
2人目: Satoさんは95点です
3人目: Suzukiさんは60点です

ソースコードの解説

user_scores.items() はキーと値のペアを返します。

これを enumerate に渡すことで、処理順序に連番を振ることができます。

ただし、辞書型は本来「キーで値を検索するもの」であり「順序」に依存するロジックを組むことは推奨されません。

あくまで表示上の連番や、処理の進捗ログを表示する際などに利用するのが良いでしょう。

Pythonのスキルを活かして年収を上げる方法

以上、Pythonのfor文でインデックス付きでループする方法について解説してきました。

なお、Pythonのスキルがある場合には、「転職して年収をアップさせる」「副業で稼ぐ」といった方法を検討するのがおすすめです。

Pythonエンジニアの需要は非常に高いため、転職によって数十万円の年収アップはザラで、100万円以上年収が上がることも珍しくありません。

なお、転職によって年収を上げたい場合は、エンジニア専門の転職エージェントサービスを利用するのが最適です。

今すぐ転職する気がなくとも、とりあえず転職エージェントに無料登録しておくだけで、スカウトが届いたり、思わぬ好待遇の求人情報が送られてきたりするというメリットがあります。

併せて、副業案件を獲得できるエージェントにも登録しておくと、空いている時間を活かして稼げるようなPythonの案件を探しやすくなります。

転職エージェントも副業エージェントも、登録・利用は完全無料なので、どんな求人や副業案件があるのか気になる方は、気軽に利用してみるとよいでしょう。

タイトルとURLをコピーしました