【Python入門】enumerateでindex付きのループをしよう!辞書やJSONも


Pythonのリストを要素だけじゃなくてインデックス付きで取得したい

辞書やJSONもインデックス付きで取得できたら良いんだけど……

enumerate関数ってなに?  基本的な使い方を知りたい!

リストや辞書の要素を取得するとき、繰り返し処理のfor文を使うことが多いと思います。でも、「要素だけじゃなくてインデックスも取得したい」なんてケースも多くありますよね。

そんなとき、range関数を使っていたりしませんか? それなら、今日からはenumerate関数を使ってみましょう!

「enumerate」を使うと、リストの要素とインデックスのセットを簡単に取得できます。この記事では、リストや辞書、JSONの全要素をインデックス付きで処理するコードを紹介します。

こんな方はぜひ最後までお付き合いください!

  • リスト・辞書の要素をインデックス付きで取得したい方
  • JSONの要素もインデックス付きで取得したい方

なお、この記事のサンプルコードはPython 3.7.3で実装および動作確認を致しました。

Pythonのenumerate関数とは

以下の「sample.py」を見てください。

items = ['要素1', '要素2', '要素3']
for item in items:
    print(item)

これを以下のコマンドで実行すると、

$ python sample.py

 

実行結果:

要素1
要素2
要素3

普通に要素が取り出せましたね。これでじゅうぶんな事も多くありますが、一方で要素だけではなく「これが何番目の要素か」という情報(=インデックス)が欲しくなるケースもよくあります。

そんなときに使えるのが、enumerate関数です。

enumerate関数は、繰り返し処理の中でリストや辞書の要素をインデックス付きで取得することができます。for文と組み合わせれば、全要素とそれぞれのインデックスの取得が可能です。

0 要素1
1 要素2
2 要素3

 

一例として、実際のコードを見てみましょう。enumerate関数は2行目で使われています。

enumerate関数の書き方:

fruits = ['apple', 'orange', 'banana']
for (i,j) in enumerate(fruits): #enumerate(リスト)という形
    print(i,j)

 

実行結果:

0 apple
1 orange
2 banana

どうでしょう? for文とほとんど変わらないコード量で、0,1,2と番号が付けられていますね。

実行結果からiが0から1ずつ増えているのが読み取れます。このiインデックスといいます

以下の記事ではenumerateの基本的な使い方を取り上げていますので、あわせてご覧いただければと思います。

【Python入門】enumerate関数とfor文でindexを取得しよう
更新日 : 2020年5月8日

enumerate関数の使い方【基本編】

まずはenumerateの基本的な使い方を解説します。

基本構文

for 変数1,変数2 in enumerate(リスト等の変数):
    #for文の中身

このように記述すると、変数1にインデックスの値が代入されて、変数2にリストの要素が代入されていきます。

また、それぞれの変数名に縛りは特にありません。

インデックスの開始番号を指定したい場合

enumerate関数では、start引数を指定することで、インデックスの開始番号を自由に設定する事ができます。

以下のコードでは、試しに1を指定してみました。

fruits = ['apple', 'orange', 'banana']
for (i,j) in enumerate(fruits, start=1):
    print(i,j)

 

実行結果:

1 apple
2 orange
3 banana

実行結果を見てみると、インデックスが0からではなく、1から始まっていますね。

enumerate関数の使い方【応用編】

次は、応用的な使い方です。

辞書の全要素をインデックス付きで取得する方法

ここでは、辞書をenumerateで要素を取り出します。リストと同じようにコードを書いてみましょう。

X3 = {"taro": "pw1", "hanako": "pw2", 
      "itiro": "pw3", "yui": "pw4"}
 
for (k,v) in enumerate(X3):
    print(k,v)

 

実行結果:

0 taro
1 hanako
2 itiro
3 yui

確かにインデックスは付いていますが、辞書のキーのみが出力されていて"pw1"などが取れていません。これでは意味がありませんね。

そこで辞書に「辞書.items()」とすると、要素をリストで出力できるのはご存知でしょうか。辞書の要素をリストにできれば、enumerateと組み合わせて使えますね。

X3 = {"taro": "pw1", "hanako": "pw2", 
      "itiro": "pw3", "yui": "pw4"}
 
for (k,v) in enumerate(X3.items()):
    print(k,v)

 

実行結果:

0 ('taro', 'pw1')
1 ('hanako', 'pw2')
2 ('itiro', 'pw3')
3 ('yui', 'pw4')

これで全要素をインデックス付きで取得できました。なお、辞書の取り扱いについては、以下の記事でも紹介していますので、あわせてご覧ください。

【Python入門】dictionary(辞書)の使い方。基本と応用
更新日 : 2019年7月30日

JSONの全要素をインデックス付きで取得する方法

最後にJSONの全要素をインデックス付きで取得する方法です。

読み込むJSONファイルは以下のとおりです。ファイル名は、test.jsonとしました。

{
    "profile1": {
        "first": "Tarou",
        "last": "Tanaka"
    },
    "profile2": {
        "first": "Hanako",
        "last": "Yamada"
    }
}

JSONは、json.load()で辞書として読み込めますので、辞書をリストにしてenumerateと組み合わせる方法を使えば良さそうですよね。

しかし、JSONは階層が深くなることがあるので注意が必要です。そこで以下の点を工夫します。

  • enumerate_dict関数を定義して再帰的に呼び出す
  • インデックスは階層構造を反映した形にするため、リストのappend(), pop()を使って格納する
import json
 
def enumerate_dict(dic, idx):
    for (i,v) in enumerate(dic.items()):
        idx.append(i)
        if (isinstance(v[1],dict)): #次の階層がある場合
            print(idx, v[0])
            enumerate_dict(v[1],idx)
        else: #次の階層が無い場合
            print(idx, v)
        idx.pop()

idx = []
with open('test.json', 'r') as f:
    json_dict = json.load(f)
    enumerate_dict(json_dict, idx)

 

実行結果:

[0] profile1
[0, 0] ('first', 'Tarou')
[0, 1] ('last', 'Tanaka')
[1] profile2
[1, 0] ('first', 'Hanako')
[1, 1] ('last', 'Yamada')

これでJsonの階層構造を反映した形で取得できました。

インデックスだけが取得したい場合の書き方

これは書き方のお話ですが、インデックスだけ必要で、要素は使わないという場合はその旨を明示的に書いておく方が可読性が高まります。

具体的にfor文を

for インデックス, _(アンダースコア) in リスト:

と記述する事で、要素の部分は使わないという事が示せます。

fruits = ['apple', 'orange', 'banana']
for i,_ in enumerate(fruits, start=1): #要素の箇所は"_"とする
    print(i)

 

実行結果:

1
2
3

"i, v"として、vを使わないという形式でも処理に違いはありませんが、「ここでは使わないよ」という意思表示があると、後々メンテナンスしやすくなることもありますので覚えておきましょう。

まとめ

今回の記事では、enumerate関数を使ってリストや辞書、JSONの要素をインデックス付きで取得する方法を説明しました。

JSONのインデックスについては通し番号のほうが良いという考え方もあると思いますが、複雑なJSONであっても対応できますので、参考までに知っておいていただけると嬉しいです!

for文+カウンタ用の変数を使うよりも、enumerateを使って記述した方がスマートなコードになります。是非ここで使い方を覚えて、活用していってください!

「プログラミング、右も左もわからない…」という方にオススメ

当プログラミングスクール「侍エンジニア塾」では、これまで6000人以上のエンジニアを輩出してきました。

その経験を通してプログラミング学習に成功する人は、「目的目標が明確でそれに合わせた学習プランがあること」「常に相談できる人がそばにいること」「自己解決能力が身につくこと」この3つが根付いている傾向を発見しました。

侍エンジニア塾は上記3つの成功ポイントを満たすようなサービス設計に磨きをかけております。

cta_under_bnr

「自分のスタイルや目的に合わせて学習を進めたいな」とお考えの方は、ぜひチェックしてみてください。

書いた人

侍テック編集部

侍エンジニア塾は「人生を変えるプログラミング学習」をコンセンプトに、過去多くのフリーランスエンジニアを輩出したプログラミングスクールです。侍テック編集部では技術系コンテンツを中心に有用な情報を発信していきます。
サービスページはこちら
ツイッターはこちら
フェイスブックはこちら

おすすめコンテンツ

まずはここから!初心者でも1から学べるプログラミング入門カリキュラム

転職成功で受講料0円!あなたもプログラミングを学んでエンジニアデビュー