对于列表["foo", "bar", "baz"]
和列表"bar"
中的项目,如何在Python中获取其索引(1)?
答案 0 :(得分:3871)
>>> ["foo", "bar", "baz"].index("bar")
1
参考:Data Structures > More on Lists
请注意,虽然这可能是回答问题的最简洁方法,但index
是list
API的一个相当弱的组件,我不能记得我最后一次愤怒地使用它。在评论中已经向我指出,因为这个答案被大量引用,所以应该更加完整。关于list.index
的一些警告如下。最初可能需要查看文档字符串:
>>> 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)
快大约五个数量级,因为前者只需搜索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
的阻止中(可能更快,至少当搜索列表很长时,该项目通常存在。)答案 1 :(得分:835)
学习Python真正有用的一件事是使用交互式帮助功能:
>>> help(["foo", "bar", "baz"])
Help on list object:
class list(object)
...
|
| index(...)
| L.index(value, [start, [stop]]) -> integer -- return first index of value
|
通常会引导您找到您正在寻找的方法。
答案 2 :(得分:491)
大多数答案解释了如何找到单个索引,但如果项目多次出现在列表中,则它们的方法不会返回多个索引。使用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
答案 3 :(得分:139)
获取所有索引:
indexes = [i for i,x in enumerate(xs) if x == 'foo']
答案 4 :(得分:120)
index()
会返回第一个值的索引!
|指数(...)
| L.index(value,[start,[stop]]) - &gt;整数 - 返回第一个值索引
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"])
答案 5 :(得分:72)
如果元素不在列表中,则会出现问题。此函数处理问题:
# 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
答案 6 :(得分:66)
a = ["foo","bar","baz",'bar','any','much']
indexes = [index for index in range(len(a)) if a[index] == 'bar']
答案 7 :(得分:46)
您必须设置条件以检查您要搜索的元素是否在列表中
if 'your_element' in mylist:
print mylist.index('your_element')
else:
print None
答案 8 :(得分:39)
这里提出的所有功能都重现了固有的语言行为,但却模糊了正在发生的事情。
[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 :(得分:34)
如果您想要所有索引,则可以使用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),)
这是一个清晰易读的解决方案。
答案 10 :(得分:25)
在Python中找到包含它的列表的项目的索引
对于列表
["foo", "bar", "baz"]
和列表"bar"
中的项目,在Python中获取索引(1)的最简洁方法是什么?
嗯,当然,还有索引方法,它返回第一次出现的索引:
>>> 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)
如果您有pandas,可以使用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
就相当冗长了 - 我宁愿避免这种情况。
我通常会在列表上进行迭代,所以我通常会指向任何有趣的信息,获取index with enumerate.
如果您正在重复数据,那么您应该使用pandas - 它比我已经展示的纯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)
这些用法似乎有一个共同点,就是它们似乎在约束大小的列表上运行(因为list.index
的O(n)查找时间很重要),并且它们主要用于解析(和空闲时的UI)。
虽然有用例,但它们并不常见。如果您发现自己正在寻找这个答案,那么问问自己,您所做的事情是否是对您的用例语言提供的工具的最直接用法。
答案 11 :(得分:21)
具有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')
答案 12 :(得分:16)
使用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
答案 13 :(得分:16)
另一个选择
>>> 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]
>>>
答案 14 :(得分:15)
只需你可以选择
a = [['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']]
b = ['phone', 'lost']
res = [[x[0] for x in a].index(y) for y in b]
答案 15 :(得分:13)
...就像在获取索引之前确认项目的存在一样。这种方法的好处是函数总是返回一个索引列表 - 即使它是一个空列表。它也适用于字符串。
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]
>>>
这样的事情:
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在earlier answer中提出的建议。当我最初回答这个问题时,我甚至没有看到那个答案,因为我不明白。我希望我更冗长的例子有助于理解。
如果仍然上面的单行代码 对您没有意义,我强烈建议您使用Google'python list comprehension'并花几分钟时间熟悉自己。它只是使用Python开发代码的许多强大功能之一。
答案 16 :(得分:12)
来自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被调用的次数,但是效率没有保证。
答案 17 :(得分:10)
此解决方案不如其他解决方案强大,但如果您是初学者且只知道for
循环,则仍然可以在避免ValueError的同时找到项目的第一个索引:
def find_element(p,t):
i = 0
for e in p:
if e == t:
return i
else:
i +=1
return -1
答案 18 :(得分: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
答案 19 :(得分:5)
由于Python列表从零开始,我们可以使用zip内置函数,如下所示:
>>> [i for i,j in zip(range(len(haystack)), haystack) if j == 'needle' ]
其中“haystack”是有问题的列表,“needle”是要查找的项目。
(注意:这里我们使用i来迭代获取索引,但如果我们需要关注项目,我们可以切换到j。)
答案 20 :(得分:4)
在列表L中查找项目x的索引:
idx = L.index(x) if (x in L) else -1
答案 21 :(得分:3)
如果找不到该项,Python index()
方法会抛出错误,这很糟糕!
相反,你可以使它类似于JavaScript的indexOf()
函数,如果找不到该项,则返回-1
:
try:
index = array.index('search_keyword')
except ValueError:
index = -1
答案 22 :(得分: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))))))
答案 23 :(得分:2)
如@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
安装。
答案 24 :(得分:2)
让我们将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
答案 25 :(得分:1)
对于那些来自像我这样的其他语言的人来说,可能只需要一个简单的循环就可以更容易理解和使用它:
mylist = ["foo", "bar", "baz", "bar"]
newlist = enumerate(mylist)
for index, item in newlist:
if item == "bar":
print(index, item)
我很感谢 So what exactly does enumerate do? 。这让我明白了。
答案 26 :(得分:1)
在众多答案中都提到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]
答案 27 :(得分:1)
如果您要一次查找索引,则可以使用“索引”方法。但是,如果您要多次搜索数据,则建议使用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
答案 28 :(得分:1)
AddFileForDownload
# Throws ValueError if nothing is found
some_list = ['foo', 'bar', 'baz'].index('baz')
# some_list == 2
some_list = [item1, item2, item3]
# Throws StopIteration if nothing is found
# *unless* you provide a second parameter to `next`
index_of_value_you_like = next(
i for i, item in enumerate(some_list)
if item.matches_your_criteria())
答案 29 :(得分:1)
该值可能不存在,因此为避免发生ValueError,我们可以检查该值是否确实存在于列表中。
list = ["foo", "bar", "baz"]
item_to_find = "foo"
if item_to_find in list:
index = list.index(item_to_find)
print("Index of the item is " + str(index))
else:
print("That word does not exist")
答案 30 :(得分:1)
它只使用 python 函数 array.index()
和一个简单的 Try/Except,如果在列表中找到它,它返回记录的位置,如果在列表中找不到它,则返回 -1(如带有 indexOf()
函数的 JavaScript)。
fruits = ['apple', 'banana', 'cherry']
try:
pos = fruits.index("mango")
except:
pos = -1
在这种情况下,列表 fruits
中不存在“mango”,因此 pos
变量为 -1,如果我搜索了“cherry”,则 pos
变量将为 2 .
答案 31 :(得分: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]
答案 32 :(得分:0)
为防止ValueError,尽管类也可以工作,但您可以使函数实现此功能。
def findInList(List, item):
try:
return List.index(item)
except ValueError:
return -1
唯一的问题是它可能导致难以跟踪的错误;其他号码也一样。
但是,如果返回的不是数字,则可能会用作列表索引,并且无论如何都会不可避免地引发错误。
我认为,如果找不到该项目,就出了点问题,最好使用try
-except
,但要使用自定义错误消息,因此不会增加调试的难度,返回值也无关紧要:
# python 3.x
class itemNotFoundInListError(Exception):
pass
def findInList(List, item):
try:
return List.index(item)
except ValueError:
raise itemNotFoundInListError(f"List `{List}` does not contain `{item}.`")
答案 33 :(得分:0)
简单选项:
a = ["foo", "bar", "baz"]
[i for i in range(len(a)) if a[i].find("bar") != -1]