查找列表中项的索引

Finding the index of an item in a list

提问人:Eugene M 提问时间:10/7/2008 最后编辑:Mateen UlhaqEugene M 更新时间:10/28/2023 访问量:6155572

问:

给定一个列表和列表中的一个项目,我如何获取它的索引?["foo", "bar", "baz"]"bar"1

Python 列表 索引

评论

14赞 Ṃųỻịgǻňạcểơửṩ 5/13/2018
你是否返回: [1] 如果有多个实例,则为最低索引,[2] 的所有索引 ?"bar""bar"
6赞 smci 5/21/2018
a) 是否保证项目在列表中,或者我们应该如何处理错误情况?(return None/ raise ValueError) b) 列表条目是否保证是唯一的,我们应该返回匹配的第一个索引,还是所有索引?
1赞 Athanassios 1/28/2020
查看答案 numpy 集成,numpy 数组比 Python 列表效率高得多。如果列表很短,那么从 Python 列表中复制它是没有问题的,如果不是,那么也许你应该首先考虑将元素存储在 numpy 数组中。
0赞 Karl Knechtel 12/27/2022
我投票关闭这个问题(以示抗议),因为已经有 42 个未删除的答案(还有 16 个已删除)用于一个简单的单行参考问题,几乎所有答案的核心都具有相同的内置功能(他们应该这样做,因为这是解决问题的唯一合理和理智的方法,围绕它的一切都只是错误检查或创造性地重新解释规范, 这仍然只剩下另一种合理、理智的方法来解决扩展的问题)。
0赞 Karl Knechtel 12/27/2022
在未来的 Python 版本中,没有更好的方法成为可能,因为现有的方法已经只是调用列表中的一个内置方法——尽可能简单。

答:

5934赞 Alex Coventry 10/7/2008 #1
>>> ["foo", "bar", "baz"].index("bar")
1

有关列表的内置方法,请参阅文档.index()

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

在值等于 x 的第一项的列表中返回从零开始的索引。如果没有此类项,则引发 ValueError

可选参数 startend 被解释为切片表示法,用于将搜索限制为列表的特定子序列。返回的索引是相对于完整序列的开头计算的,而不是相对于开始参数计算的。

警告

列表长度的线性时间复杂度

调用按顺序检查列表的每个元素,直到找到匹配项。如果列表很长,并且不能保证该值将接近开头,则可能会减慢代码速度。index

这个问题只能通过使用不同的数据结构来完全避免。但是,如果已知元素位于列表的某个部分内,则可以使用 和 参数来缩小搜索范围。startend

例如:

>>> 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

第二个调用的速度要快几个数量级,因为它只需要搜索 10 个元素,而不是全部 100 万个元素。

仅返回第一个匹配项的索引

按顺序搜索列表,直到找到匹配项,然后停止的调用。如果该值可能出现多个,并且需要所有索引,则无法解决问题:indexindex

>>> [1, 1].index(1) # the `1` index is not found.
0

相反,使用列表推导式或生成器表达式进行搜索,并使用枚举来获取索引

>>> # A list comprehension gives a list of indices directly:
>>> [i for i, e in enumerate([1, 2, 1]) if e == 1]
[0, 2]
>>> # A generator comprehension gives us an iterable object...
>>> g = (i for i, e in enumerate([1, 2, 1]) if e == 1)
>>> # which can be used in a `for` loop, or manually iterated with `next`:
>>> next(g)
0
>>> next(g)
2

如果只有一个匹配项,列表推导和生成器表达式技术仍然有效,并且更通用。

如果没有匹配项,则引发异常

如上面的文档中所述,如果搜索的值不在列表中,using 将引发异常:.index

>>> [1, 1].index(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 2 is not in list

如果这是一个问题,请先使用 显式检查,或根据需要使用 / 处理异常。item in my_listtryexcept

显式检查简单易读,但它必须再次迭代列表。有关此选择的更多指导,请参阅 Python 中的 EAFP 原则是什么?

评论

43赞 mold 1/30/2018
index 返回值为“bar”的第一项。如果“bar”在列表中存在两次,则永远无法找到第二个“bar”的键。请参阅文档:docs.python.org/3/tutorial/datastructures.html
10赞 slybloty 9/20/2019
如果你只搜索一个元素(第一个),我发现这比列表推导对整数列表的推导快不到 90%。index()
2赞 izhang05 2/23/2020
如果列表很长,应该使用什么数据结构?
1赞 Alex Coventry 2/24/2020
@izhang:一些辅助索引,如 {element -> list_index} dict,如果元素是可散列的,并且列表中的位置很重要。
1赞 Alex Coventry 3/15/2021
@jvel07,请参阅我答案中的列表/生成器理解示例。
156赞 HongboZhu 8/30/2011 #2

index()返回第一个 value 索引!

|索引(...)
|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"])

评论

3赞 Peter Mortensen 6/5/2018
如果列表中不存在?
1赞 Nam G VU 8/13/2018
不存在的项将引发 ValueError
1赞 Cristik 2/10/2019
这个答案更适合这里:stackoverflow.com/questions/6294179/......
109赞 savinson 8/21/2012 #3
a = ["foo","bar","baz",'bar','any','much']

indexes = [index for index in range(len(a)) if a[index] == 'bar']
108赞 tanzil 4/16/2013 #4

如果该元素不在列表中,则会出现问题。此函数处理以下问题:

# 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
55赞 Graham Giller 5/17/2013 #5

这里提出的所有函数都重现了固有的语言行为,但模糊了正在发生的事情。

[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

如果语言提供了执行您想要执行的操作的方法,为什么还要编写具有异常处理功能的函数?

评论

10赞 Eric Duminil 2/5/2017
第 3 种方法对列表进行两次迭代,对吧?
1赞 Peter Mortensen 6/5/2018
回复:“这里所有建议的函数”:也许在撰写本文时,但您应该检查更新的答案,看看它是否仍然正确。
25赞 kiriloff 5/29/2013 #6

简单地说,你可以

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

res = [[x[0] for x in a].index(y) for y in b]
21赞 Mathitis2Software 5/30/2013 #7

另一种选择

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

评论

3赞 Cristik 2/10/2019
这个答案应该更好地发布在这里:stackoverflow.com/questions/6294179/......
0赞 ggorlen 5/14/2023
这与这个问题有什么关系?
710赞 TerryA 6/20/2013 #8

大多数答案解释了如何查找单个索引,但如果项目多次出现在列表中,则其方法不会返回多个索引。使用 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() 的小解决方案(这与 enumerate 的方法几乎相同):

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赞 Tupelo Thistlehead 10/27/2017
对我来说,枚举比基于索引的方法效果更好,因为我希望使用 'startswith“ 收集字符串的索引,并且我需要收集多个实例。或者有没有办法将索引与我无法弄清楚的“startswith”一起使用
9赞 Alex Coventry 11/18/2017
在我手中,枚举版本始终略快。自上述测量结果发布以来,某些实现细节可能已更改。
4赞 Cristik 2/10/2019
自 11 年以来,这个问题已经得到回答:stackoverflow.com/questions/6294179/......
0赞 UnusualWays 2/13/2023
在 Python 3 中应替换为内置的 .看这里izipzip
1赞 Brian Keith 6/1/2023
这是一个很好的解决方案,它比公认的解决方案灵活得多。例如,如果列表中只有 1 个值,则可以添加 if 语句以引发异常,否则只能返回if len([i for i, j in enumerate(['foo', 'bar', 'baz']) if j == 'bar']) > 1[i for i, j in enumerate(['foo', 'bar', 'baz']) if j == 'bar'][0]
240赞 FMc 6/25/2013 #9

要获取所有索引,请执行以下操作:

indexes = [i for i, x in enumerate(xs) if x == 'foo']

评论

7赞 Cristik 2/10/2019
这已经有另一个问题了,在 11 年添加了:stackoverflow.com/questions/6294179/......
16赞 bvanlew 3/28/2014 #10

来自 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 的次数,但无法保证效率。

评论

2赞 Cristik 2/10/2019
这个答案应该更好地发布在这里:stackoverflow.com/questions/6294179/......
74赞 user3670684 5/26/2014 #11

您必须设置一个条件来检查您正在搜索的元素是否在列表中

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

评论

2赞 devssh 9/10/2018
这有助于我们避免尝试捕获!
4赞 stefanct 9/6/2019
但是,它可能会使复杂性增加一倍。有人检查过吗?
2赞 ApproachingDarknessFish 1/29/2020
@stefanct 时间复杂度仍然是线性的,但它会在列表中循环两次。
1赞 stefanct 1/29/2020
@ApproachingDarknessFish这显然是我的意思。即使从迂腐的角度来看,它的复杂程度相同,但在许多用例中,迭代两次可能是一个严重的缺点,因此我提出了它。我们仍然不知道答案......
1赞 Matthew Strasiotto 6/27/2021
@stefanct这可能会使复杂性增加一倍,但我相信列表中的运算符具有线性运行时。@ApproachingDarknessFish表示它会迭代两次来回答你的问题,并且说线性复杂性加倍并不是什么大问题。在许多用例中,我不会将重复列表两次称为严重缺点,因为复杂性理论告诉我们 O(n) + O(n) -> O(2*n) -> O(n),即 - 变化通常可以忽略不计。in
21赞 MrWonderful 12/31/2014 #12

而现在,对于完全不同的东西......

...就像在获取索引之前确认项目的存在一样。这种方法的好处是函数总是返回一个索引列表——即使它是一个空列表。它也适用于字符串。

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开发,我对我原来的答案有点尴尬,所以为了澄清事实,当然可以使用上面的代码;但是,获得相同行为的更惯用的方法是使用列表推导式以及 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 在他之前的回答中建议的。在我最初回答这个问题的时候,我什至没有看到那个答案,因为我不明白。我希望我这个更冗长的例子将有助于理解。

如果上面的单行代码对你来说仍然没有意义,我强烈建议你谷歌“python列表推导”,并花几分钟时间熟悉一下。这只是众多强大的功能之一,使使用 Python 开发代码成为一种乐趣。

13赞 dylankb 5/17/2015 #13

这个解决方案不如其他解决方案强大,但如果你是一个初学者,只知道循环,仍然可以找到一个项目的第一个索引,同时避免 ValueError:for

def find_element(p,t):
    i = 0
    for e in p:
        if e == t:
            return i
        else:
            i +=1
    return -1
6赞 Coder123 7/5/2015 #14
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

26赞 Arnaldo P. Figueira Figueira 11/11/2015 #15

所有带有 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')

评论

3赞 Cristik 2/10/2019
这个答案应该更好地发布在这里:stackoverflow.com/questions/6294179/......
0赞 ggorlen 5/14/2023
enumerate(xs)比 更清晰。此外,这并不能回答这个问题。zip(xs, range(len(xs))
62赞 rbrisuda 11/18/2015 #16

如果你想要所有索引,那么你可以使用 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),)

这是一个清晰、可读的解决方案。

评论

5赞 András Aszódi 10/12/2016
字符串列表、非数字对象列表等呢??
2赞 Cristik 2/10/2019
这个答案应该更好地发布在这里:stackoverflow.com/questions/6294179/......
1赞 Athanassios 1/28/2020
这是我读过的最好的一本。numpy 数组比 Python 列表效率高得多。如果列表很短,那么从 Python 列表中复制它是没有问题的,如果不是,那么开发人员可能应该首先考虑将元素存储在 numpy 数组中。
34赞 PythonProgrammi 8/8/2017 #17

获取列表中一个或多个(相同)项的所有出现次数和位置

使用 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

评论

2赞 Cristik 2/10/2019
这个答案应该更好地发布在这里:stackoverflow.com/questions/6294179/......
5赞 jihed gasmi 8/13/2017 #18

由于 Python 列表是从零开始的,我们可以按如下方式使用 zip 内置函数:

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

其中“Haystack”是有问题的列表,“Needle”是要查找的项目。

(注意:这里我们使用 i 来迭代获取索引,但如果我们需要专注于项目,我们可以切换到 j。

评论

5赞 PythonProgrammi 12/27/2017
我认为 [i for i,j in enumerate(haystack) if j=='needle'] 更紧凑和可读。
56赞 Russia Must Remove Putin 8/22/2017 #19

在 Python 中查找给定包含它的列表的项目的索引

对于列表和列表中的项目,在 Python 中获取其索引 (1) 的最干净方法是什么?["foo", "bar", "baz"]"bar"

嗯,当然,有 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

这样做的缺点是,您可能会检查返回的值或 None:isis 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 问题吗?

XY 问题是询问您尝试的解决方案,而不是您的实际问题。

为什么你认为你需要在列表中给定一个元素的索引?

如果你已经知道这个值,你为什么要关心它在列表中的位置?

如果值不存在,则捕获 是相当冗长的 - 我宁愿避免这种情况。ValueError

无论如何,我通常会遍历列表,因此我通常会保留指向任何有趣信息的指针,并使用枚举获取索引。

如果你正在整理数据,你可能应该使用 pandas - 它比我展示的纯 Python 变通方法有更优雅的工具。

我不记得自己需要。但是,我已经浏览了 Python 标准库,我发现它有一些很好的用途。list.index

它在 、 GUI 和文本解析中有很多很多用途。idlelib

该模块使用它来查找模块中的注释标记,以通过元编程自动重新生成其中的关键字列表。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),并且它们主要用于解析(在空闲的情况下使用 UI)。list.index

虽然它有用例,但它们相当罕见。如果你发现自己在寻找这个答案,问问自己,你正在做的是否是该语言为你的用例提供的工具的最直接使用。

4赞 mold 1/31/2018 #20

对于那些像我这样来自其他语言的人来说,也许通过一个简单的循环更容易理解和使用它:

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

我很感谢 那么枚举到底是做什么的?这帮助我理解了。

评论

0赞 mold 6/7/2023
这只是一个示例,用于了解如何查找重复项 - 枚举有助于做到这一点。
0赞 mold 8/16/2023
@ggorlen我理解了你关于我用来定义结果的 newlist 变量。这就是为什么我切断了那条线并将枚举函数放在循环中。现在好多了。请记住,所有东西都是 Python 中的一个对象,但当然,您可以像官方文档那样将枚举作为“内置”函数调用。而且,当我使用 enumerate 将列表排序时,我将继续拥有一个列表。否则,您需要将其称为字典,但事实并非如此。enumerate(mylist)
8赞 Hamed Baatour 3/4/2018 #21

如果未找到该项,Python 方法将引发错误。因此,您可以使其类似于 JavaScript 的函数,如果未找到该项,则返回该函数:index()indexOf()-1

def indexof( array, elem):
try:
    return array.index(elem)
except ValueError:
    return -1

评论

8赞 Sapphire_Brick 10/30/2019
然而,JavaScript 的理念是奇怪的结果比错误好,所以返回 -1 是有意义的,但在 Python 中,它可能使一个难以追踪的错误,因为 -1 从列表末尾返回一个项目。
0赞 Sergio Abreu 10/27/2023
-1 在 java/javascript 中并不是一个奇怪的结果。它是“未在列表中找到”的语言组合。可以在 Python 中使用这种 java 智能进行简单的验证:如果 theindex > -1: 或者如果 theindex >= 0: 这也会做同样的事情。
7赞 Ankit Gupta 3/8/2018 #22

对此有一个更实用的答案。

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赞 y2k-shubham 8/21/2018
这个答案对于函数式编程爱好者来说感觉宾至如归Scala
0赞 Caveman 6/23/2020
当具有许多匹配项的列表中只需要一个值时,此值需要很长时间。
15赞 Ketan 5/26/2018 #23

查找列表 L 中项目 x 的索引:

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

评论

6赞 Cristik 2/10/2019
这会迭代数组两次,因此可能会导致大型数组的性能问题。
0赞 Ketan 7/23/2022
@Cristik - 正确。如果列表长度没有合理的下限,则不适用。
0赞 Ketan 7/23/2022
应仅用于非重复性任务/部署,或者如果列表长度相对较小,不会明显影响整体性能。
5赞 FatihAkici 9/11/2018 #24

如果性能受到关注:

在许多答案中都提到,方法的内置方法是 O(n) 算法。如果您需要执行一次,这很好。但是,如果您需要多次访问元素的索引,则首先创建一个项目-索引对的字典 (O(n)),然后在每次需要时访问位于 O(1) 的索引会更有意义。list.index(item)

如果您确定列表中的项目永远不会重复,则可以轻松:

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]
3赞 pylang 9/25/2018 #25

正如@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 进行安装。

3赞 Siddharth Satpathy 11/15/2018 #26

让我们为您拥有的列表命名。可以将列表转换为 .然后,使用 numpy.where 获取列表中所选项目的索引。以下是您将实现它的方式。lstlstnumpy array

import numpy as np

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

>>> 1

评论

0赞 Caveman 6/23/2020
如果项是类的实例,则不起作用
1赞 sahasrara62 3/18/2019 #27

使用字典,其中首先处理列表,然后向其添加索引

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]
5赞 Vlad Bezden 4/4/2020 #28

如果您要查找一次索引,那么使用“索引”方法可以。但是,如果您要多次搜索数据,那么我建议使用 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

评论

0赞 ggorlen 5/14/2023
“在我的机器上使用二分模块比使用索引方法快 20 倍”,这是描述两种算法之间关系的一种有点不准确的方式。这不是一个线性关系,所以在10个元素的小列表中,两种算法的性能应该大致相同。在稍大的列表中,您可能会开始注意到差异。在海量列表中,二进制搜索的速度可能快数千倍。
7赞 Caveman 6/23/2020 #29

对于一个可比的

# 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())

按谓词查找所有项的索引

index_of_staff_members = [
    i for i, user in enumerate(users)
    if user.is_staff()]

评论

0赞 tejasvi88 12/10/2020
idx = next((i for i, v in enumerate(ls) if v == chk), -1)获取类似于 str.index(chk) 的行为。
0赞 Caveman 12/10/2020
@tejasvi88 决定在答案上做一些额外的工作
10赞 Badri Paudel 8/28/2020 #30

该值可能不存在,因此为了避免此 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") 

评论

0赞 ggorlen 5/14/2023
调用变量会覆盖内置函数。调用 ,则表示您正在执行两次搜索。最好/按照其他线程中的建议。listinindextryexcept.index()
8赞 Blackjack 4/10/2021 #31

它只使用 python 函数,并使用简单的 Try / Except 如果在列表中找到记录,则返回记录的位置,如果在列表中找不到,则返回 -1(就像在 JavaScript 上使用函数一样)。array.index()indexOf()

fruits = ['apple', 'banana', 'cherry']

try:
  pos = fruits.index("mango")
except:
  pos = -1

在这种情况下,“芒果”不在列表中,因此变量为 -1,如果我搜索“樱桃”,变量将为 2。fruitspospos

-1赞 illuminato 5/4/2021 #32

简单的选项:

a = ["foo", "bar", "baz"]
[i for i in range(len(a)) if a[i].find("bar") != -1]

评论

1赞 Mehmet Burak Sayıcı 9/20/2021
并非列表中的每个元素都是字符串。
5赞 MD SHAYON 10/3/2021 #33

我发现这两个解决方案更好,我自己尝试了

>>> expences = [2200, 2350, 2600, 2130, 2190]
>>> 2000 in expences
False
>>> expences.index(2200)
0
>>> expences.index(2350)
1
>>> index = expences.index(2350)
>>> expences[index]
2350

>>> try:
...     print(expences.index(2100))
... except ValueError as e:
...     print(e)
... 
2100 is not in list
>>> 


1赞 Abdul Niyas P M 11/28/2021 #34

Pythonic 方式可以使用,但您也可以从模块中使用 indexOf。请注意,如果 b 不在 a 中,这将引发 ValueErrorenumerateoperator

>>> from operator import indexOf
>>>
>>>
>>> help(indexOf)
Help on built-in function indexOf in module _operator:

indexOf(a, b, /)
    Return the first index of b in a.

>>>
>>>
>>> indexOf(("foo", "bar", "baz"), "bar") # with tuple
1
>>> indexOf(["foo", "bar", "baz"], "bar") # with list
1
2赞 Franz Gastring 12/30/2021 #35

python 中的某些结构包含一个索引方法,可以很好地解决这个问题。

'oi tchau'.index('oi')     # 0
['oi','tchau'].index('oi') # 0
('oi','tchau').index('oi') # 0

引用:

在列表中

在元组中

在字符串中

4赞 sargupta 1/7/2022 #36
text = ["foo", "bar", "baz"]
target = "bar"

[index for index, value in enumerate(text) if value == target]

对于一小部分元素,这将正常工作。但是,如果 列表包含大量元素,最好应用二进制 使用 O(log n) 运行时复杂度进行搜索

评论

0赞 ggorlen 5/14/2023
如果列表已排序,并且排序为 O(n log(n)),则只能进行二叉搜索。
19赞 LunaticXXD10 1/14/2022 #37

下面是使用 Python 函数的两行代码:index()

LIST = ['foo' ,'boo', 'shoo']
print(LIST.index('boo'))

输出:1

11赞 Kofi 2/7/2022 #38

列表推导是在查找列表中的项的索引时获得紧凑实现的最佳选择。

a_list = ["a", "b", "a"]
print([index for (index , item) in enumerate(a_list) if item == "a"])

评论

0赞 Rolf of Saxony 11/22/2023
也适用于整数和浮点数,以及查找所有出现的情况
33赞 Babatunde Mustapha 4/17/2022 #39
me = ["foo", "bar", "baz"]
me.index("bar") 

您可以将此项应用于列表的任何成员以获取其索引

-1赞 Deepeshkumar 5/5/2022 #40

可以使用 zip() 函数来获取列表中值的索引。代码可以是;

list1 = ["foo","bar","baz"]
for index,value in zip(range(0,len(list1)),list1):
    if value == "bar":
        print(index)

评论

1赞 Wondercricket 6/8/2022
zip(range(0,len(list1)),list1)当你可以做的时候,是矫枉过正enumerate(list1)
1赞 LunaticXXD10 7/4/2022
代码是矫枉过正
4赞 My Car 10/2/2022 #41

请尝试以下代码:

["foo", "bar", "baz"].index("bar")

参考:https://www.programiz.com/python-programming/methods/list/index

0赞 saolof 12/14/2022 #42

不要。如果绝对需要,请使用列表中的方法。然而,这需要线性时间,如果你发现自己伸手去拿它,你可能滥用列表来做一些你不应该用它们做的事情。.index(item...)

最有可能的是,您关心的是 1) 整数和项目之间的双向映射,或者 2) 在排序的项目列表中查找项目。

对于第一个,使用一对词典。如果您想要一个可以为您执行此操作的库,请使用该库。bidict

对于第二个,使用可以正确利用列表排序这一事实的方法。使用 python 中的内置模块。bisect

如果您发现自己想要在排序列表中插入项目,也不应使用排序列表。要么使用内置模块将排序需求弱化为堆,要么使用库。heapqsortedcontainers

使用不是为您要执行的操作而设计的数据结构是一种不好的做法。使用与您赋予的任务相匹配的解决方案,既可以向读者传达您想要执行特定操作的信息,也可以使您的解决方案在实践中更快/更具可扩展性。

0赞 Sanu 1/8/2023 #43

python 中的简单解决方案:

li1=["foo","bar","baz"]
for i in range(len(li1)):
     if li1[i]=="bar":
          print(i)

列表元素的数据类型无关紧要。只需将“bar”替换为您要查找的元素即可。我们也可以为此编写一个函数,如下所示:

def indexfinder(element,lis):
    for i in range(len(lis)):
        if lis[i]==element:
            return i
1赞 ggorlen 5/14/2023 #44

令人惊讶的是,此评论中提到的 next 的回退值第二个参数尚未在此处显示。

当您可以比较整个对象时,基本功能效果很好,但通常需要通过某个属性搜索特定项目的对象或字典列表,在这种情况下,带有条件的生成器是自然的选择:.index()

>>> users = [{"id": 2, "name": "foo"}, {"id": 3, "name": "bar"}]
>>> target_id = 2
>>> found_user = next(x for x in users if x["id"] == target_id)
>>> found_user
{'id': 2, 'name': 'foo'}

这停在第一个匹配元素上,并且相当简洁。

但是,如果没有找到匹配的元素,则会引发错误,这有点尴尬。幸运的是,它提供了第二个参数回退,以提供更自然、更自由的控制流:StopIterationnextnext(gen, default)except

>>> found_user = next((x for x in users if x["id"] == target_id), None)
>>> if not found_user:
...     print("user not found")
... 
user not found

这有点冗长,但仍然相当可读。

如果需要索引:

>>> found_idx = next((i for i, x in enumerate(users) if x["id"] == 1), None)
>>> found_idx
None
>>> next((i for i, x in enumerate(users) if x["id"] == 3), None)
1

正如此评论所指出的,最好不要为缺失的索引返回典型的 -1,因为这是 Python 中的有效索引。如果看起来很奇怪,提高是合适的。None

这些有点冗长,但如果您重复使用它,请随意将代码隐藏在帮助程序函数中,提供任意谓词。

>>> def find(it, pred):
...     return next((x for x in it if pred(x)), None)
...
>>> find(users, lambda user: user["id"] == 2)
{'id': 2, 'name': 'foo'}
>>> print(find(users, lambda user: user["id"] == 42))
None
>>> find("foobAr", str.isupper) # works on any iterable!
'A'
0赞 Hadi Mir 9/22/2023 #45

在列表中查找元素索引的最简单方法之一是执行以下操作

arr = ["foo", "bar", "baz"] 
el = "bar"
try:
  index = arr.index(el)
  return index
except:
  return 'element not found'

0赞 Alejadro Xalabarder 10/27/2023 #46

类似于其他语言的函数“indexof”,如果找不到元素,则 returs -1 可以写成

def indexof (obj, elem, offset=0):
    if elem in obj[offset:]:
        return offset + obj[offset:].index(elem)
    return -1


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

print (indexof(obj, "not here"))
print (indexof(obj, "baz"))
print (indexof(obj, "foo", 1))

返回

-1
2
3

或针对大列表的优化版本

def indexof (obj, elem, offset=0):
    if offset == 0:
       # no need of a sublist
       if elem in obj:
          return obj.index(elem)
       return -1

    sublist = obj[offset:]
    if elem in sublist:
        return offset + sublist.index(elem)
    return -1