リスト内のアイテムのインデックスを見つける

2008年10月07日に質問されました。  ·  閲覧回数 4.2M回  ·  ソース

Eugene M picture
2008年10月07日

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

回答

Alex Coventry picture
2008年10月07日
4781
>>> ["foo", "bar", "baz"].index("bar")
1

参照:データ構造>リストの詳細

警告が続きます

これはおそらく質問に答える最もクリーンな方法ですindexlist APIのかなり弱いコンポーネントであり、最後に使用したときのことを思い出せないことに注意してください。怒り。 コメントの中で、この回答は頻繁に参照されているため、より完全なものにする必要があると指摘されています。 list.indexに関するいくつかの警告が続きます。 最初にそのドキュメントを確認する価値があります。

list.index(x[, start[, end]])

値がxに等しい最初のアイテムのリストでゼロベースのインデックスを返します。 そのようなアイテムがない場合、 ValueError上げます。

オプションの引数startおよびendは、スライス表記の場合と同様に解釈され、検索をリストの特定のサブシーケンスに制限するために使用されます。 返されるインデックスは、開始引数ではなく、完全なシーケンスの先頭を基準にして計算されます。

リスト長の線形時間計算量

index呼び出しは、一致するものが見つかるまで、リストのすべての要素を順番にチェックします。 リストが長く、リストのどこで発生するかが大まかにわからない場合、この検索がボトルネックになる可能性があります。 その場合は、別のデータ構造を検討する必要があります。 一致する場所が大まかにわかっている場合は、 indexにヒントを与えることができます。 たとえば、このスニペットでは、 l.index(999_999, 999_990, 1_000_000)はストレートl.index(999_999)よりも約5桁高速です。これは、前者が10エントリを検索するだけで、後者が100万を検索するためです。

>>> 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. index呼び出しをValueErrorをキャッチするtry/exceptブロックでラップします(少なくとも検索するリストが長く、アイテムが通常存在する場合は、おそらくより高速です)。
davidavr picture
2008年10月07日
922

Pythonの学習に本当に役立つことの1つは、インタラクティブなヘルプ機能を使用することです。

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

class list(object)
 ...

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

それはしばしばあなたが探している方法にあなたを導くでしょう。

TerryA picture
2013年06月20日
591

回答の大部分は、単一のインデックスを見つける方法を説明していますが、アイテムがリストに複数回ある場合、それらのメソッドは複数のインデックスを返しません。 enumerate()使用します:

for i, j in enumerate(['foo', 'bar', 'baz']):
    if j == 'bar':
        print(i)

index()関数は最初のオカレンスのみを返しますが、 enumerate()はすべてのオカレンスを返します。

リスト内包として:

[i for i, j in enumerate(['foo', 'bar', 'baz']) if j == 'bar']

itertools.count()した別の小さなソリューションもあります(これは列挙とほぼ同じアプローチです)。

from itertools import izip as zip, count # izip for maximum efficiency
[i for i, j in zip(count(), ['foo', 'bar', 'baz']) if j == 'bar']

これは、 enumerate()を使用するよりも大きなリストの場合に効率的です。

$ python -m timeit -s "from itertools import izip as zip, count" "[i for i, j in zip(count(), ['foo', 'bar', 'baz']*500) if j == 'bar']"
10000 loops, best of 3: 174 usec per loop
$ python -m timeit "[i for i, j in enumerate(['foo', 'bar', 'baz']*500) if j == 'bar']"
10000 loops, best of 3: 196 usec per loop
FMc picture
2013年06月25日
188

すべてのインデックスを取得するには:

indexes = [i for i,x in enumerate(xs) if x == 'foo']
HongboZhu picture
2011年08月30日
137

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"])
tanzil picture
2013年04月16日
89

要素がリストにない場合、問題が発生します。 この関数は問題を処理します:

# if element is found it returns index of element else returns None

def find_element_in_list(element, list_element):
    try:
        index_element = list_element.index(element)
        return index_element
    except ValueError:
        return None
savinson picture
2012年08月21日
83
a = ["foo","bar","baz",'bar','any','much']

indexes = [index for index in range(len(a)) if a[index] == 'bar']
user3670684 picture
2014年05月26日
59

検索している要素がリストにあるかどうかを確認するための条件を設定する必要があります

if 'your_element' in mylist:
    print mylist.index('your_element')
else:
    print None
Graham Giller picture
2013年05月17日
45

ここで提案されているすべての関数は、固有の言語動作を再現しますが、何が起こっているのかをあいまいにします。

[i for i in range(len(mylist)) if mylist[i]==myterm]  # get the indices

[each for each in mylist if each==myterm]             # get the items

mylist.index(myterm) if myterm in mylist else None    # get the first index and fail quietly

言語がそれ自体でやりたいことを行うためのメソッドを提供しているのに、なぜ例外処理を伴う関数を書くのですか?

rbrisuda picture
2015年11月18日
43

すべてのインデックスが必要な場合は、 NumPyを使用できます。

import numpy as np

array = [1, 2, 1, 3, 4, 5, 1]
item = 1
np_array = np.array(array)
item_index = np.where(np_array==item)
print item_index
# Out: (array([0, 2, 6], dtype=int64),)

それは明確で読みやすい解決策です。