リスト ["foo", "bar", "baz"]
とリスト内のアイテム "bar"
に対して、Pythonでそのインデックス(1)を得るにはどうすればよいですか?
>>> ["foo", "bar", "baz"].index("bar")
1
リファレンスです。Data Structures > More on Lists
しかし、index
はlist
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 "<stdin>", line 1, in <module>
ValueError: 2 is not in list
アイテムがリストに存在しない可能性がある場合、次のいずれかを行う必要があります。
1.最初に item in my_list
でアイテムをチェックする (クリーンで読みやすいアプローチ)、または
2.2. index
呼び出しを try/except
ブロックで囲み、ValueError
をキャッチする (少なくとも、検索するリストが長く、アイテムが通常存在する場合には、おそらくより速くなります)。
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"])