Pythonで、ある項目を含むリストからその項目のインデックスを見つける

リスト ["foo", "bar", "baz"] とリスト内のアイテム "bar" に対して、Pythonでそのインデックス(1)を得るにはどうすればよいですか?

ソリューション
>>> ["foo", "bar", "baz"].index("bar")
1

リファレンスです。Data Structures > More on Lists

警告に従う

しかし、indexlist APIの中でもかなり弱いコンポーネントであり、最後に怒涛のように使ったのを覚えていません。コメントで指摘されたのですが、この回答は頻繁に参照されているので、もっと完全なものにすべきだと思います。続いて、list.indexについての注意点を説明します。おそらく、最初にdocstringを見てみる価値はあるでしょう。

>>> print(list.index.__doc__)
L.index(value, [start, [stop]]) -> integer -- return first index of value.
Raises ValueError if the value is not present.

リストの長さにおける線形時間複雑性

indexコールは、マッチするものが見つかるまで、リストのすべての要素を順にチェックします。リストが長く、リストのどこにマッチがあるか大体わからない場合、この検索がボトルネックになる可能性があります。そのような場合には、別のデータ構造を検討する必要があります。なお、マッチする場所がだいたいわかっている場合は、indexにヒントを与えることができます。例えば、このスニペットでは、l.index(999_999, 999_990, 1_000_000)は、l.index(999_999)`をそのまま使うよりも、およそ5桁速いです。

>>> import timeit
>>> timeit.timeit('l.index(999_999)', setup='l = list(range(0, 1_000_000))', number=1000)
9.356267921015387
>>> timeit.timeit('l.index(999_999, 999_990, 1_000_000)', setup='l = list(range(0, 1_000_000))', number=1000)
0.0004404920036904514

引数に 最初にマッチした インデックスのみを返します。

index`の呼び出しは、マッチするものが見つかるまでリストを順に検索し、そこで 停止します。 もし、より多くのマッチのインデックスが必要になることが予想される場合は、リスト内包やジェネレータ式を使うべきです。

>>> [1, 1].index(1)
0
>>> [i for i, e in enumerate([1, 2, 1]) if e == 1]
[0, 2]
>>> g = (i for i, e in enumerate([1, 2, 1]) if e == 1)
>>> next(g)
0
>>> next(g)
2

かつては index を使っていたほとんどの場所で、今はリスト内包やジェネレータ式を使っています。もしあなたが index を使おうと思っているなら、これらの優れた python の機能を見てみてください。

リストに要素が存在しない場合に投げる

indexの呼び出しでは、アイテムが存在しない場合にValueError` が発生します。

>>> [1, 1].index(2)
Traceback (most recent call last):
  File "", line 1, in 
ValueError: 2 is not in list

アイテムがリストに存在しない可能性がある場合、次のいずれかを行う必要があります。

1.最初に item in my_list でアイテムをチェックする (クリーンで読みやすいアプローチ)、または 2.2. index 呼び出しを try/except ブロックで囲み、ValueError をキャッチする (少なくとも、検索するリストが長く、アイテムが通常存在する場合には、おそらくより速くなります)。

解説 (2)

Pythonの学習にとても役立つのが、インタラクティブ・ヘルプ機能を使うことです。

>>> help(["foo", "bar", "baz"])
Help on list object:

class list(object)
 ...

 |
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value
 |

を使うと、探しているメソッドにたどり着くことができます。

解説 (1)

index()は、値の最初のインデックスを返します!

| index(...) | L.index(value, [start, [stop]]) -> integer -- 値の最初のインデックスを返す

def all_indices(value, qlist):
    indices = []
    idx = -1
    while True:
        try:
            idx = qlist.index(value, idx+1)
            indices.append(idx)
        except ValueError:
            break
    return indices

all_indices("foo", ["foo","bar","baz","foo"])
解説 (3)