リスト["foo", "bar", "baz"]
とリスト"bar"
内の項目の場合、Pythonでindex(1)を取得するにはどうすればよいですか?
>>> ["foo", "bar", "baz"].index("bar")
1
参照: データ構造>リストの詳細
これはおそらく質問に答える最も明快な方法ですが 尋ねられるように ですが、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桁速くなっています。前者は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
項目がリストに表示されていない可能性がある場合は、
item in my_list
(きれいで読みやすいアプローチ)でチェックする、またはindex
呼び出しをValueError
をキャッチするtry/except
ブロックでラップします(少なくとも検索するリストが長く、通常は項目が存在する場合はおそらく高速です)。Pythonを学ぶのに本当に役立つことの一つは、対話型ヘルプ機能を使うことです。
>>> help(["foo", "bar", "baz"])
Help on list object:
class list(object)
...
|
| index(...)
| L.index(value, [start, [stop]]) -> integer -- return first index of value
|
それはしばしばあなたが探している方法にあなたを導くでしょう。
回答の大半は、 単一のインデックス を見つける方法を説明していますが、アイテムがリストに複数回含まれている場合、それらのメソッドは複数のインデックスを返しません。 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()
を使ったもう1つの小さな解決策です(これは列挙とほとんど同じ方法です)。
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
すべてのインデックスを取得するには
indexes = [i for i,x in enumerate(xs) if x == 'foo']
index()
は first の値のインデックスを返します。
|インデックス(...)
| 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"])
要素がリストにない場合は問題が発生します。この機能は問題を処理します。
# 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
a = ["foo","bar","baz",'bar','any','much']
indexes = [index for index in range(len(a)) if a[index] == 'bar']
検索している要素がリストにあるかどうかを確認するための条件を設定する必要があります
if 'your_element' in mylist:
print mylist.index('your_element')
else:
print None
ここで提案されているすべての関数は固有の言語の振る舞いを再現していますが、何が起こっているのかをあいまいにしています。
[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
あなたの言語があなたが望むことをするための方法を提供するならば、なぜ例外処理で関数を書くのですか?
すべてのインデックスが必要な場合は、 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),)
それは明確で読みやすい解決策です。
Pythonでそれを含むリストを与えられたアイテムのインデックスを見つける
リスト
["foo", "bar", "baz"]
およびリスト"bar"
内の項目について、Pythonでindex(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
そして、この欠点は、戻り値is
またはis not
Noneがないかどうかを確認する必要があることです。
result = index(a_list, value)
if result is not None:
do_something(result)
あなたがもっとオカレンスを持つことができるならば、あなたはnotlist.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')
そしてそれらをリストやTupleに入れたいのなら、コンストラクタに渡してください。
>>> list(series[series == 'bar'].index)
[1, 3]
はい、リスト内包表記を列挙型で使用することもできますが、私の考えではそれほどエレガントではありません - Cで書かれた組み込みコードに処理させるのではなく、Pythonで同等性のテストを行っています。
>>> [i for i, value in enumerate(l) if value == 'bar']
[1, 3]
XY問題はあなたの実際の問題よりもむしろあなたの試みられた解決策について尋ねています。
なぜリストの要素に与えられたインデックスが必要だと思いますか?
あなたがすでにその値を知っているなら、なぜあなたはそれがリストのどこにあるかを気にかけますか?
値がそこにない場合、ValueError
を捉えるのはかなり冗長です - そして私はそれを避けることを好みます。
とにかく私はたいていリストを反復処理しています、それで私はたいていどんな興味深い情報へのポインタも保ち、列挙で インデックスを得ます。
あなたがデータを管理しているのであれば、おそらくパンダを使うべきです - これは私が示した純粋なPythonの回避策よりはるかにエレガントなツールを持っています。
私はlist.index
を必要としていることを思い出しません。しかし、私はPythonの標準ライブラリを調べました、そして私はそれのためのいくつかの優れた用途を見ます。
idlelib
には、GUIやテキストの解析のために、たくさんの用途があります。
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
Lib/tarfile.pyではdistutilsと似ていて、項目までスライスすることができます。
members = members[:members.index(tarinfo)]
Lib/pickletools.pyでは、
numtopop = before.index(markobject)
これらの用法が共通しているように見えるのは、それらが(O(n) list.index
のルックアップ時間のために重要な)制限されたサイズのリストで動作するように見えることですアイドルの場合).
それのためのユースケースがありますが、それらはかなり珍しいです。この答えを探しているのであれば、あなたがしていることがあなたのユースケースのために言語によって提供されるツールの最も直接的な使用法であるかどうか自分自身に尋ねなさい。
Zip
関数を持つすべてのインデックス:
get_indexes = lambda x, xs: [i for (y, i) in Zip(xs, range(len(xs))) if x == y]
print get_indexes(2, [1, 2, 3, 4, 5, 6, 3, 2, 3, 2])
print get_indexes('f', 'xsfhhttytffsafweef')
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]
>>>
この関数は、項目とリストを引数として取り、前に見たようにリスト内の項目の位置を返します。
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
...インデックスを取得する前にアイテムの存在を確認するようなものです。このアプローチの素晴らしい点は、空のリストであっても、関数は常にインデックスのリストを返すことです。文字列でも動作します。
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]
>>>
ヘッドダウンpython開発の1年後、私は元の答えに少し恥ずかしく思います。そのため、記録をまっすぐにするには、上記のコードを使用できます。ただし、同じ動作を得るためのmuchより慣用的な方法は、enumerate()関数とともにリスト内包表記を使用することです。
このようなもの:
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つにすぎません。
ただ一緒に行くことができます
a = [['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']]
b = ['phone', 'lost']
res = [[x[0] for x in a].index(y) for y in b]
別のオプション
>>> a = ['red', 'blue', 'green', 'red']
>>> b = 'red'
>>> offset = 0;
>>> indices = list()
>>> for i in range(a.count(b)):
... indices.append(a.index(b,offset))
... offset = indices[-1]+1
...
>>> indices
[0, 3]
>>>
FMcとuser7177からの答えの変形は、あらゆるエントリのすべてのインデックスを返すことができる辞書を与えるでしょう:
>>> 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)を使用しました。
この解決法は他のものほど強力ではありませんが、あなたが初心者でfor
loopsについてだけ知っているのであればValueErrorを避けながらアイテムの最初のインデックスを見つけることはまだ可能です:
def find_element(p,t):
i = 0
for e in p:
if e == t:
return i
else:
i +=1
return -1
Pythonリストはゼロから始まるので、Zip組み込み関数を次のように使用できます。
>>> [i for i,j in Zip(range(len(haystack)), haystack) if j == 'needle' ]
"haystack"は問題のリストで、 "needle"は探す項目です。
(注:ここでは、インデックスを取得するためにiを使用して繰り返していますが、アイテムに焦点を合わせる必要がある場合は、jに切り替えることができます。)
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になります。
リストLの項目xのインデックスを見つける:
idx = L.index(x) if (x in L) else -1
リストに繰り返し項目がない場合は、インデックスを確認する必要があります。
eg: li=[10,20,30] # here need to get index of 20 means
li.index(20) # will work properly because 20 is not repeated
繰り返しても最初のインデックスしか表示されない
アイテムが存在するすべてのインデックスを取得する必要がある場合
eg: li=[10,20,30,20,40, 50, 10] # here need to get index of 20 means its have 2 index (1,3)
あなたがそれをする必要があることを得るために
li=[10,20,30,20,40, 50, 10]
[i for i, e in enumerate(li) if e == 20]
[1,3]のようにo/pとしてインデックスのリストを取得します。
これに対するもっと機能的な答えがあります。
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))))))
アイテムが見つからなかった場合、Pythonのindex()
メソッドはエラーをスローします。
そのため、代わりに、アイテムが見つからなかった場合に-1
を返すJavaScriptのindexOf()
関数に似たものにすることができます。
try:
index = array.index('search_keyword')
except ValueError:
index = -1
リストに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
@TerryAで示されるように、one indexを見つける方法について多くの回答が話し合っています。
more_itertools
はmultipleインデックスをイテラブル内で検索するためのツールを備えたサードパーティのライブラリです。
与えられた
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
からインストールしてください。
私のような他の言語から来た人たちにとっては、たぶん簡単なループで理解して使うのが簡単でしょう:
mylist = ["foo", "bar", "baz", "bar"]
newlist = enumerate(mylist)
for index, item in newlist:
if item == "bar":
print(index, item)
に感謝します。それで、正確に列挙は何をするのでしょうか?。それは私が理解するのを助けました。
list.index(item)
メソッドの組み込みメソッドはO(n)アルゴリズムであることが多くの回答で言及されています。あなたがこれを一度実行する必要があればそれは結構です。しかし、要素のインデックスに何度もアクセスする必要がある場合は、最初にアイテムとインデックスのペアの辞書(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]
辞書を使用して、ここで最初にリストを処理してからそれにインデックスを追加します
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]