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


3182

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


6
あなたは戻ってきている:[1]のインスタンスが複数ある場合には、最低指数"bar"、[2]すべてのインデックス"bar"
Ṃųỻịgǻňạcểơửṩ

4
a)アイテムがリストに含まれていることは保証されていますか、それともエラーの場合の処理​​方法は?(Noneを返す/ ValueErrorを発生させる)b)リストエントリは一意であることが保証されていますか。一致の最初のインデックス、またはすべてのインデックスを返す必要がありますか?
smci 2018年

numpy統合で回答を表示します。numpy配列はPythonリストよりもはるかに効率的です。リストが短い場合は、Pythonリストからコピーを作成しても問題ありません。そうでない場合は、最初に要素をnumpy配列に格納することを検討してください。
アサナシオス

回答:


4486
>>> ["foo", "bar", "baz"].index("bar")
1

リファレンス:データ構造>リストの詳細

警告が続く

これはおそらく、質問に答えるためのクリーンな方法である一方であること注尋ねたとしてindexのかなり弱い部品であるlistAPI、そして私は、私は怒りでそれを使用した最後の時間を思い出すことができません。この回答は頻繁に参照されているため、より完全にする必要があるというコメントで指摘されました。list.indexフォローに関するいくつかの注意事項。おそらく最初にそのドキュメントを見てみる価値があります。

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

値がxに等しい最初の項目のリストでゼロから始まるインデックスを返します。ValueErrorそのようなアイテムがない場合はaを発生させます。

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

リストの長さの線形時間複雑性

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

リストに要素が存在しない場合にスローされます

を呼び出すと、アイテムが存在しない場合はindexaに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するtry/exceptブロックで呼び出しをラップしますValueError(おそらくより高速で、少なくとも検索するリストが長く、アイテムが通常存在する場合)。

20
indexは、値が「bar」である最初のアイテムを返します。リストに「バー」が2回存在する場合、2番目の「バー」のキーは見つかりません。ドキュメントを参照:docs.python.org/3/tutorial/datastructures.html
mpoletto

2
1つの要素(最初の要素)のみを検索している場合index()、整数のリストに対するリストの理解よりも90%ほど高速であることがわかりました。
slybloty

リストが非常に長い場合、どのデータ構造を使用する必要がありますか?
izhang05

@izhang:要素がハッシュ可能で、リスト内の位置が重要である場合、{element-> list_index}辞書などのいくつかの補助インデックス。
アレックスコベントリー

899

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
 |

多くの場合、あなたが探している方法にたどり着きます。


2
bpythonは、インタラクティブな方法でドキュメントを読むための優れたユーザーフレンドリーな方法です。
goetzc

@davidavrはい、しかし、ヘルプドキュメントをスクロールする代わりにグーグルしたい残りの私たちには、このすばらしい中央のランク付けされたオプションセットはありません。:)
honkaboy

556

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

'startswith "を使用して文字列のインデックスを収集しようとしているため、列挙はインデックスベースのメソッドよりもうまく機能し、複数のオカレンスを収集する必要があります。または、" startswith "でインデックスを使用する方法があります。理解できなかった
Tupelo Thistlehead '26 / 10/26

3
私の手では、列挙バージョンは一貫してわずかに高速です。上記の測定値が投稿されてから、実装の詳細の一部が変更されている可能性があります。
Alex Coventry

2
これは、すでに'11以来答えた:stackoverflow.com/questions/6294179/...
Cristik


132

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"])

2
そして、リストに存在しない場合はどうなりますか?
Peter Mortensen

1
存在しないアイテムはValueErrorを発生させます
Nam G VU

1
この回答は、ここでより良いフィットします:stackoverflow.com/questions/6294179/...
Cristik

86

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

# 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


58

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

if 'your_element' in mylist:
    print mylist.index('your_element')
else:
    print None

1
これは、キャッチを回避するのに役立ちます!
devssh 2018

ただし、複雑さが2倍になる可能性があります。誰か確認しましたか?
stefanct

@stefanct時間の複雑さは依然として線形ですが、リストを2回繰り返します。
DarknessFishへの接近

@ApproachingDarknessFishそれは明らかに私が言ったことです。たとえそれが同じ順序で複雑であっても、2回の反復は多くのユースケースで深刻な欠点になる可能性があるため、私はそれを提示しました。そして、まだ答えはわかりません...
stefanct

44

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

[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

言語があなた自身がやりたいことをするメソッドを提供しているのに、なぜ例外処理付きの関数を書くのですか?


9
3番目のメソッドは、リストを2回繰り返しますよね?
Eric Duminil、2017

Re:「ここで提案されているすべての機能」:執筆時点ではおそらくですが、新しい回答をチェックして、それがまだ正しいかどうかを確認する必要があります。
Peter Mortensen

41

すべてのインデックスが必要な場合は、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),)

明確で読みやすいソリューションです。


4
文字列のリスト、非数値オブジェクトのリストなどはどうですか?
Laryx Decidua

1
この回答はより良いここに掲載する必要があります。stackoverflow.com/questions/6294179/...
Cristikを

1
これは私が読んだ中で最高のものです。numpy配列はPythonリストよりもはるかに効率的です。リストが短い場合は、Pythonリストからコピーを作成しても問題ありません。そうでない場合、開発者は最初に要素をnumpy配列に格納することを検討する必要があります。
アサナシオス

35

Pythonでアイテムを含むリストを指定してアイテムのインデックスを見つける

リスト["foo", "bar", "baz"]とリスト内のアイテムについて、"bar"Pythonでそのインデックス(1)を取得する最もクリーンな方法は何ですか?

まあ、確かに、最初の出現のインデックスを返すindexメソッドがあります:

>>> l = ["foo", "bar", "baz"]
>>> l.index('bar')
1

この方法にはいくつかの問題があります。

  • 値がリストにない場合は、 ValueError
  • リストに複数の値がある場合、最初の値のインデックスのみを取得します

値なし

値が欠落している可能性がある場合は、をキャッチする必要がありますValueError

これは、次のような再利用可能な定義で行うことができます。

def index(a_list, value):
    try:
        return a_list.index(value)
    except ValueError:
        return None

次のように使用します。

>>> print(index(l, 'quux'))
None
>>> print(index(l, 'bar'))
1

そして、これの欠点は、おそらく戻り値isis notNone かどうかのチェックがあることです:

result = index(a_list, value)
if result is not None:
    do_something(result)

リストに複数の値

さらに多く発生する可能性がある場合、次のコマンドで完全な情報を取得できませlist.index

>>> l.append('bar')
>>> l
['foo', 'bar', 'baz', 'bar']
>>> l.index('bar')              # nothing at index 3?
1

インデックスを理解しているリストに列挙するかもしれません:

>>> [index for index, v in enumerate(l) if v == 'bar']
[1, 3]
>>> [index for index, v in enumerate(l) if v == 'boink']
[]

オカレンスがない場合は、結果のブール値チェックでそれをチェックするか、結果をループする場合は何もしないことができます。

indexes = [index for index, v in enumerate(l) if v == 'boink']
for index in indexes:
    do_something(index)

パンダとのより良いデータ交換

パンダがある場合は、Seriesオブジェクトを使用してこの情報を簡単に取得できます。

>>> import pandas as pd
>>> series = pd.Series(l)
>>> series
0    foo
1    bar
2    baz
3    bar
dtype: object

比較チェックは一連のブール値を返します:

>>> series == 'bar'
0    False
1     True
2    False
3     True
dtype: bool

その一連のブール値を添え字表記を介してシリーズに渡すと、一致するメンバーのみが取得されます。

>>> series[series == 'bar']
1    bar
3    bar
dtype: object

インデックスのみが必要な場合、index属性は一連の整数を返します。

>>> series[series == 'bar'].index
Int64Index([1, 3], dtype='int64')

そして、それらをリストまたはタプルに入れたい場合は、コンストラクタに渡してください:

>>> list(series[series == 'bar'].index)
[1, 3]

はい、リスト内包表記を列挙と一緒に使用することもできますが、私の意見では、それほどエレガントではありません-Cで記述された組み込みコードに処理を任せる代わりに、Pythonで同等性のテストを行っています。

>>> [i for i, value in enumerate(l) if value == 'bar']
[1, 3]

これはXY問題ですか?

XY問題は、実際の問題ではなく、試みた解決策について尋ねています。

リストの要素に与えられたインデックスが必要だと思うのはなぜですか?

すでに価値を知っているなら、なぜそれがリストのどこにあるのか気にするのですか?

値がそこにない場合、キャッチValueErrorはかなり冗長です-そして私はそれを避けることを好みます。

私は通常、とにかくリストを反復処理しているので、通常は興味深い情報へのポインターを保持し、列挙型インデックスを取得します。

データを変更する場合は、おそらくパンダを使用する必要があります。これは、私が示した純粋なPythonの回避策よりもはるかに洗練されたツールです。

list.index自身が必要だったことを思い出しません。しかし、Python標準ライブラリを調べたところ、いくつかの優れた使用法が見つかりました。

idlelibGUIとテキスト解析では、多くの用途があります。

keywordそれは自動的にメタプログラミングを経由して、その中にキーワードのリストを再生成するモジュールでコメントマーカーを見つけるためのモジュールが使用します。

Lib / mailbox.pyでは、それを順序付けられたマッピングのように使用しているようです:

key_list[key_list.index(old)] = new

そして

del key_list[key_list.index(key)]

Lib / http / cookiejar.pyでは、次の月を取得するために使用されているようです:

mon = MONTHS_LOWER.index(mon.lower())+1

distutilsに似たLib / tarfile.pyで、アイテムまでのスライスを取得します。

members = members[:members.index(tarinfo)]

Lib / pickletools.pyで:

numtopop = before.index(markobject)

これらの使用法に共通しているように見えるのは、制約されたサイズのリスト(O(n)のルックアップ時間のために重要)を操作しているように見えlist.index、解析(およびIdleの場合はUI)で主に使用されていることです。

それのユースケースはありますが、それらはかなりまれです。この答えを探している場合は、使用している言語で提供されているツールを最も直接使用しているのかどうかを自問してください。



21

リスト内の1つ以上の(同一の)アイテムのすべての出現と位置を取得する

enumerate(alist)を使用すると、要素xが探しているものと等しい場合に、リストのインデックスである最初の要素(n)を格納できます。

>>> alist = ['foo', 'spam', 'egg', 'foo']
>>> foo_indexes = [n for n,x in enumerate(alist) if x=='foo']
>>> foo_indexes
[0, 3]
>>>

関数findindexを作成しましょう

この関数は引数としてアイテムとリストを取り、前に見たようにリスト内のアイテムの位置を返します。

def indexlist(item2find, list_or_string):
  "Returns all indexes of an item in a list or a string"
  return [n for n,item in enumerate(list_or_string) if item==item2find]

print(indexlist("1", "010101010"))

出力


[1, 3, 5, 7]

シンプルな

for n, i in enumerate([1, 2, 3, 4, 1]):
    if i == 1:
        print(n)

出力:

0
4

1
この回答はより良いここに掲載する必要があります。stackoverflow.com/questions/6294179/...
Cristikを

16

単にあなたは一緒に行くことができます

a = [['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']]
b = ['phone', 'lost']

res = [[x[0] for x in a].index(y) for y in b]


15

そして今、まったく違う何かのために...

...インデックスを取得する前にアイテムの存在を確認するようなものです。このアプローチの良い点は、関数が常にインデックスのリストを返すことです-空のリストであっても。文字列でも動作します。

def indices(l, val):
    """Always returns a list containing the indices of val in the_list"""
    retval = []
    last = 0
    while val in l[last:]:
            i = l[last:].index(val)
            retval.append(last + i)
            last += i + 1   
    return retval

l = ['bar','foo','bar','baz','bar','bar']
q = 'bar'
print indices(l,q)
print indices(l,'bat')
print indices('abcdaababb','a')

インタラクティブなpythonウィンドウに貼り付けた場合:

Python 2.7.6 (v2.7.6:3a1db0d2747e, Nov 10 2013, 00:42:54) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def indices(the_list, val):
...     """Always returns a list containing the indices of val in the_list"""
...     retval = []
...     last = 0
...     while val in the_list[last:]:
...             i = the_list[last:].index(val)
...             retval.append(last + i)
...             last += i + 1   
...     return retval
... 
>>> l = ['bar','foo','bar','baz','bar','bar']
>>> q = 'bar'
>>> print indices(l,q)
[0, 2, 4, 5]
>>> print indices(l,'bat')
[]
>>> print indices('abcdaababb','a')
[0, 4, 5, 7]
>>> 

更新

もう1年間ヘッズダウンでPythonを開発した後、元の答えに少し困惑したので、記録を正直に設定するには、上記のコードを使用できます。しかし、多くの同じ動作を取得するために、より慣用的な方法は、列挙()関数と一緒に、リストの内包表記を使用することです。

このようなもの:

def indices(l, val):
    """Always returns a list containing the indices of val in the_list"""
    return [index for index, value in enumerate(l) if value == val]

l = ['bar','foo','bar','baz','bar','bar']
q = 'bar'
print indices(l,q)
print indices(l,'bat')
print indices('abcdaababb','a')

対話型のpythonウィンドウに貼り付けると、次のようになります。

Python 2.7.14 |Anaconda, Inc.| (default, Dec  7 2017, 11:07:58) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def indices(l, val):
...     """Always returns a list containing the indices of val in the_list"""
...     return [index for index, value in enumerate(l) if value == val]
... 
>>> l = ['bar','foo','bar','baz','bar','bar']
>>> q = 'bar'
>>> print indices(l,q)
[0, 2, 4, 5]
>>> print indices(l,'bat')
[]
>>> print indices('abcdaababb','a')
[0, 4, 5, 7]
>>> 

そして今、この質問とすべての回答を検討した結果、これがFMcが彼の以前の回答で提案したとおりであることを理解しました。私が最初にこの質問に答えたとき、私はそれを理解していなかったので、その答えすらませんでした。私のやや冗長な例が理解に役立つことを願っています。

上記の1行のコードでも問題が解決しない場合は、Googleの「Pythonリストの理解」を理解し、慣れるまでに数分かかることを強くお勧めします。これは、Pythonを使用してコードを開発することを喜びにする多くの強力な機能の1つにすぎません。


12

FMcおよびuser7177からの回答のバリアントは、任意のエントリのすべてのインデックスを返すことができるdictを提供します。

>>> a = ['foo','bar','baz','bar','any', 'foo', 'much']
>>> l = dict(zip(set(a), map(lambda y: [i for i,z in enumerate(a) if z is y ], set(a))))
>>> l['foo']
[0, 5]
>>> l ['much']
[6]
>>> l
{'baz': [2], 'foo': [0, 5], 'bar': [1, 3], 'any': [4], 'much': [6]}
>>> 

これを1つのライナーとして使用して、1つのエントリのすべてのインデックスを取得することもできます。ラムダが呼び出される回数を減らすためにset(a)を使用しましたが、効率の保証はありません。


1
この回答はより良いここに掲載する必要があります。stackoverflow.com/questions/6294179/...
Cristikを

10

このソリューションは他のソリューションほど強力ではありませんが、初心者でforループについてのみ知っている場合でも、ValueErrorを回避しながら、アイテムの最初のインデックスを見つけることができます。

def find_element(p,t):
    i = 0
    for e in p:
        if e == t:
            return i
        else:
            i +=1
    return -1

9

リストLで項目xのインデックスを検索:

idx = L.index(x) if (x in L) else -1

4
これにより、アレイが2回繰り返されるため、大規模なアレイのパフォーマンスの問題が発生する可能性があります。
クリスティック

同意します。リストがかなり長い場合は、別の方法を探します。ただし、中小規模のリストでは大したことではありません。
ケタン

5

Pythonリストはゼロベースであるため、次のようにzip組み込み関数を使用できます。

>>> [i for i,j in zip(range(len(haystack)), haystack) if j == 'needle' ]

ここで、「haystack」は問題のリストであり、「needle」は検索する項目です。

(注:ここでは、インデックスを取得するためにiを使用して反復していますが、アイテムに集中する必要がある場合は、jに切り替えることができます。)


3
[i for i、j in enumerate(haystack)if j == 'needle']の方がコンパクトで読みやすいと思います。
Giovanni G. PY 2017

5
name ="bar"
list = [["foo", 1], ["bar", 2], ["baz", 3]]
new_list=[]
for item in list:
    new_list.append(item[0])
print(new_list)
try:
    location= new_list.index(name)
except:
    location=-1
print (location)

文字列もリストにない場合は、これが原因です。リストにない場合は、 location = -1


4

index()アイテムが見つからなかった場合、Python メソッドはエラーをスローします。そのため、代わりに、アイテムが見つからなかった場合indexOf()に返さ-1れるJavaScript の関数のようにすることができます。

try:
    index = array.index('search_keyword')
except ValueError:
    index = -1

5
ただし、JavaScriptは奇妙な結果がエラーよりも優れているという哲学を持っているため、-1を返すのは理にかなっていますが、-1はリストの最後から項目を返すため、Pythonではバグの追跡が困難になる可能性があります。
Sapphire_Brick

3

これにはより機能的な答えがあります。

list(filter(lambda x: x[1]=="bar",enumerate(["foo", "bar", "baz", "bar", "baz", "bar", "a", "b", "c"])))

より一般的な形式:

def get_index_of(lst, element):
    return list(map(lambda x: x[0],\
       (list(filter(lambda x: x[1]==element, enumerate(lst))))))

1
この答えは、のために自宅で感じているScala/ 機能プログラミング愛好家
Y2K-shubham

3

lst持っているリストに名前を付けましょう。リストlstをに変換できnumpy arrayます。そして、numpy.whereを使用して、リスト内の選択されたアイテムのインデックスを取得します。以下は、それを実装する方法です。

import numpy as np

lst = ["foo", "bar", "baz"]  #lst: : 'list' data type
print np.where( np.array(lst) == 'bar')[0][0]

>>> 1

2

私のような別の言語から来ている人にとっては、おそらく単純なループを使用すると、それを理解して使用する方が簡単です:

mylist = ["foo", "bar", "baz", "bar"]
newlist = enumerate(mylist)
for index, item in newlist:
  if item == "bar":
    print(index, item)

私は感謝していますそれで、列挙は正確に何をしますか?。それは私が理解するのに役立ちました。


2

インデックスを一度検索する場合は、「インデックス」メソッドを使用するのが適切です。ただし、データを複数回検索する場合は、bisectモジュールの使用をお勧めします。bisectモジュールを使用すると、データをソートする必要があることに注意してください。したがって、データを1回ソートすると、bisectを使用できます。使用二分私のマシン上のモジュールは、より高速なインデックスメソッドを使用するよりも20倍程度です。

Python 3.8以上の構文を使用したコードの例を次に示します。

import bisect
from timeit import timeit

def bisect_search(container, value):
    return (
      index 
      if (index := bisect.bisect_left(container, value)) < len(container) 
      and container[index] == value else -1
    )

data = list(range(1000))
# value to search
value = 666

# times to test
ttt = 1000

t1 = timeit(lambda: data.index(value), number=ttt)
t2 = timeit(lambda: bisect_search(data, value), number=ttt)

print(f"{t1=:.4f}, {t2=:.4f}, diffs {t1/t2=:.2f}")

出力:

t1=0.0400, t2=0.0020, diffs t1/t2=19.60

1

パフォーマンスが気になる場合:

メソッドの組み込みlist.index(item)メソッドはO(n)アルゴリズムであると多くの回答で言及されています。これを1回実行する必要がある場合は問題ありません。ただし、要素のインデックスに何度もアクセスする必要がある場合は、最初に項目とインデックスのペアのディクショナリ(O(n))を作成し、次に必要になるたびにO(1)のインデックスにアクセスする方が理にかなっています。それ。

リスト内のアイテムが繰り返されないことが確実な場合は、簡単に次のことができます。

myList = ["foo", "bar", "baz"]

# Create the dictionary
myDict = dict((e,i) for i,e in enumerate(myList))

# Lookup
myDict["bar"] # Returns 1
# myDict.get("blah") if you don't want an error to be raised if element not found.

要素が重複していて、そのすべてのインデックスを返す必要がある場合:

from collections import defaultdict as dd
myList = ["foo", "bar", "bar", "baz", "foo"]

# Create the dictionary
myDict = dd(list)
for i,e in enumerate(myList):
    myDict[e].append(i)

# Lookup
myDict["foo"] # Returns [0, 4]

1

@TerryAで示されているように、1つのインデックスを見つける方法については多くの回答で議論されています。

more_itertoolsイテラブル内の複数のインデックスを見つけるためのツールを備えたサードパーティのライブラリです。

与えられた

import more_itertools as mit


iterable = ["foo", "bar", "baz", "ham", "foo", "bar", "baz"]

コード

複数の観測のインデックスを見つけます。

list(mit.locate(iterable, lambda x: x == "bar"))
# [1, 5]

複数の項目をテストします。

list(mit.locate(iterable, lambda x: x in {"bar", "ham"}))
# [1, 3, 5]

のその他のオプションも参照してくださいmore_itertools.locate。を介してインストールし> pip install more_itertoolsます。


0

辞書を使用して、リストを最初に処理し、次にインデックスを追加します

from collections import defaultdict

index_dict = defaultdict(list)    
word_list =  ['foo','bar','baz','bar','any', 'foo', 'much']

for word_index in range(len(word_list)) :
    index_dict[word_list[word_index]].append(word_index)

word_index_to_find = 'foo'       
print(index_dict[word_index_to_find])

# output :  [0, 5]

-1

私の意見で["foo", "bar", "baz"].index("bar")は、それは良いですが、それは十分ではありません!「bar」が辞書にない場合、ValueError発生するので、この関数を使うことができます:

def find_index(arr, name):
    try:
        return arr.index(name)
    except ValueError:
        return -1

if __name__ == '__main__':
    print(find_index(["foo", "bar", "baz"], "bar"))

結果は次のとおりです。

1

nameがarrになかった場合、関数は-1を返します。次に例を示します。

print(find_index(["foo"、 "bar"、 "baz"]、 "fooo"))

-1


1
l = [1, 2]; find_index(l, 3)戻り-1l[find_index(l, 3)]が戻るため、これを使用しないでください2。-1を返すのは悪いことです。Noneを返すだけです。
DanielStracaboško

-1は任意の結果を返すことができるコントラクトですが、プログラムでAndroidやPHPのWebサイトなどの他のプログラムとの通信でNoneまたはNullを使用すると、プログラムが壊れる可能性があるため、NoneまたはNullを使用して、JSONでnullを返すことがあります。 Webサイトの電話アプリケーションが終了するか、エラー500(内部サーバーエラー)が返されます。
NaabNuts
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.