给定一个列表["foo", "bar", "baz"]
和列表中的项目"bar"
,如何1
在Python中获取其索引()?
给定一个列表["foo", "bar", "baz"]
和列表中的项目"bar"
,如何1
在Python中获取其索引()?
Answers:
>>> ["foo", "bar", "baz"].index("bar")
1
请注意,虽然这也许是回答这个问题最彻底的方法是问,index
是一个相当薄弱的组件list
API,而我不记得我最后一次使用它的愤怒。在评论中已向我指出,由于此答案被大量引用,因此应使其更完整。有关list.index
以下注意事项。最初值得一看它的文档可能是值得的:
list.index(x[, start[, end]])
在值等于x的第一项的列表中返回从零开始的索引。
ValueError
如果没有此类项目,则引发a 。可选参数start和end的解释与切片符号相同,用于将搜索限制到列表的特定子序列。返回的索引是相对于完整序列的开始而不是开始参数计算的。
一个index
调用检查,以列表的每一个元素,直到它找到一个匹配。如果您的列表很长,并且您大概不知道它在列表中的什么位置,则此搜索可能会成为瓶颈。在这种情况下,您应该考虑使用其他数据结构。请注意,如果您大致知道在哪里找到匹配项,则可以给出index
提示。例如,在此代码段中,l.index(999_999, 999_990, 1_000_000)
它比straight快大约五个数量级l.index(999_999)
,因为前者只需要搜索10个条目,而后者要搜索一百万个:
>>> 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
呼叫包裹在一个try/except
可以捕获的块中ValueError
(可能更快,至少在要搜索的列表较长且通常存在该项目的情况下。)index()
比对整数列表的列表理解要快90%。
学习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()
(与枚举几乎相同):
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()
返回值的第一个索引!
| 索引(...)
| L.index(value,[start,[stop]])->整数-返回值的第一个索引
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"])
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获取索引(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
无:
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]
是的,您也可以使用带有枚举的列表理解,但这在我看来并不那么优雅-您正在用Python进行相等性测试,而不是让用C编写的内置代码来处理它:
>>> [i for i, value in enumerate(l) if value == 'bar']
[1, 3]
XY问题是在询问您尝试的解决方案,而不是您的实际问题。
为什么您认为需要列表中给定元素的索引?
如果您已经知道该值,为什么还要关心它在列表中的位置?
如果值不存在,则捕获ValueError
相当冗长-我宁愿避免这种情况。
无论如何,我通常都会遍历该列表,因此我通常会保留一个指向任何有趣信息的指针,并使用枚举获取索引。
如果您要处理数据,则可能应该使用pandas-与我展示的纯Python解决方法相比,pandas的工具要优雅得多。
我不记得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(n)查找时间而很重要list.index
),并且它们主要用于解析(对于Idle,则通常用于UI)。
尽管有用例,但这种情况很少见。如果发现自己正在寻找答案,请问自己正在做的事情是否最直接地使用了该用例所用语言提供的工具。
具有该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)可以存储第一个元素(n),即元素x等于要查找的内容时列表的索引。
>>> 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
另外一个选项
>>> 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]
>>>
...就像在获取索引之前确认项目的存在。这种方法的好处是,该函数始终返回一个索引列表-即使它是一个空列表。它也适用于字符串。
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开发,我对最初的答案感到有些尴尬,因此要想保持纪录,肯定可以使用上面的代码;然而,很多更地道的方式来获得相同的行为是使用列表理解,用枚举()函数一起。
像这样:
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在他先前的答案中提出的。当我最初回答这个问题时,我什至没有看到那个答案,因为我不理解。我希望我的详细示例能有助于理解。
如果上面的单行代码对您仍然没有意义,我强烈建议您使用Google“ python list comprehension”,并花一些时间来熟悉一下自己。它只是众多强大功能之一,使使用Python开发代码感到非常高兴。
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]}
>>>
您也可以将其用作单个衬纸,以获取单个条目的所有索引。尽管我确实使用set(a)减少了调用lambda的次数,但是并不能保证效率。
在列表L中查找项目x的索引:
idx = L.index(x) if (x in L) else -1
由于Python列表是从零开始的,因此我们可以使用zip内置函数,如下所示:
>>> [i for i,j in zip(range(len(haystack)), haystack) if j == 'needle' ]
其中“ haystack”是有问题的列表,“ needle”是要查找的项目。
(注意:这里我们使用i进行迭代以获取索引,但是如果我们需要专注于项目,可以切换到j。)
index()
如果找不到该项目,Python 方法将引发错误。因此,相反,您可以使其类似于indexOf()
JavaScript 的功能,-1
如果未找到该项目,它将返回:
try:
index = array.index('search_keyword')
except ValueError:
index = -1
有一个更实用的答案。
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))))))
Scala
/ 编程功能-爱好者
让我们将名称指定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
对于那些来自像我这样的另一种语言的人,也许有一个简单的循环,它更易于理解和使用:
mylist = ["foo", "bar", "baz", "bar"]
newlist = enumerate(mylist)
for index, item in newlist:
if item == "bar":
print(index, item)
我很感激枚举到底是做什么的?。那帮助我理解了。
如果您打算一次查找索引,则可以使用“索引”方法。但是,如果要多次搜索数据,则建议使用bisect模块。请记住,使用bisect模块的数据必须进行排序。因此,您可以对数据进行一次排序,然后可以使用二等分。在我的机器上使用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
在众多答案中提到,内置方法 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]
如@TerryA所示,许多答案都讨论了如何查找一个索引。
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
。
使用dictionary,其中首先处理列表,然后向其添加索引
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]
在我看来,这["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。例如:
打印(find_index([“ foo”,“ bar”,“ baz”],“ fooo”))
-1
l = [1, 2]; find_index(l, 3)
会返回-1
并且l[find_index(l, 3)]
会返回2
。-1返回是一件坏事,只返回None。
"bar"
,[2]所有索引"bar"
?