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

Eug*_*e M 2887 python indexing list

对于列表["foo", "bar", "baz"]和列表中的项目"bar",如何在Python中获取其索引(1)?

Ale*_*try 4119

>>> ["foo", "bar", "baz"].index("bar")
1
Run Code Online (Sandbox Code Playgroud)

参考:数据结构>更多列表

警告如下

请注意,虽然这也许是回答这个问题最彻底的方法是问,index是一个相当薄弱的组件listAPI,而我不记得我最后一次使用它的愤怒.在评论中已经向我指出,因为这个答案被大量引用,所以应该更加完整.关于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.
Run Code Online (Sandbox Code Playgroud)

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

一个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
Run Code Online (Sandbox Code Playgroud)

仅将第一个匹配的索引返回到其参数

要在通话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
Run Code Online (Sandbox Code Playgroud)

我曾经使用过的大多数地方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
Run Code Online (Sandbox Code Playgroud)

如果该项目可能不在列表中,您应该

  1. 首先检查它item in my_list(干净,可读的方法),或
  2. index呼叫包裹在try/except捕获的块中ValueError(可能更快,至少当搜索列表很长时,该项通常存在.)

  • index返回值为"bar"的第一个项目.如果"bar"在列表中存在两次,您将永远找不到第二个"bar"的键.请参阅文档:https://docs.python.org/3/tutorial/datastructures.html (15认同)
  • 如果您只搜索一个元素(第一个),我发现 `index()` 比针对整数列表的列表理解快了不到 90%。 (4认同)
  • 如果列表很长,应该使用什么数据结构? (2认同)

dav*_*avr 867

学习Python真正有用的一件事是使用交互式帮助功能:

>>> help(["foo", "bar", "baz"])
Help on list object:

class list(object)
 ...

 |
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value
 |
Run Code Online (Sandbox Code Playgroud)

这通常会引导您找到您正在寻找的方法.

  • @davidavr 是的,但是我们其他人只想用谷歌搜索而不是滚动帮助文档,就没有这套漂亮的、集中的、排名的选项。:) (7认同)
  • [bpython](https://bpython-interpreter.org/screenshots.html) 是一种以交互方式阅读文档的用户友好方式。 (5认同)

Ter*_*ryA 517

大多数答案解释了如何查找单个索引,但如果项目在列表中多次,则它们的方法不会返回多个索引.用途enumerate():

for i, j in enumerate(['foo', 'bar', 'baz']):
    if j == 'bar':
        print(i)
Run Code Online (Sandbox Code Playgroud)

index()函数仅返回第一个匹配项,同时enumerate()返回所有匹配项.

作为列表理解:

[i for i, j in enumerate(['foo', 'bar', 'baz']) if j == 'bar']
Run Code Online (Sandbox Code Playgroud)

这里还有另一个小解决方案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']
Run Code Online (Sandbox Code Playgroud)

对于较大的列表,这比使用更有效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
Run Code Online (Sandbox Code Playgroud)

  • 自 11 年以来已经回答了这个问题:/sf/ask/440592561/ (4认同)
  • 对我来说,枚举比基于索引的方法更好,因为我希望使用 'startswith" 收集字符串的索引,并且我需要收集多次出现的情况。或者有没有一种方法可以使用我的 "startswith" 索引不明白 (3认同)
  • 在我手中,枚举版本始终略快.自上面的测量发布以来,一些实施细节可能已经改变. (3认同)

FMc*_*FMc 160

获取所有索引:

indexes = [i for i,x in enumerate(xs) if x == 'foo']
Run Code Online (Sandbox Code Playgroud)

  • 在'11中添加了另一个问题:/sf/ask/440592561/ (2认同)

Hon*_*Zhu 129

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"])
Run Code Online (Sandbox Code Playgroud)

  • 如果列表中不存在? (2认同)

tan*_*zil 79

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

# 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
Run Code Online (Sandbox Code Playgroud)


sav*_*son 75

a = ["foo","bar","baz",'bar','any','much']

indexes = [index for index in range(len(a)) if a[index] == 'bar']
Run Code Online (Sandbox Code Playgroud)

  • 这个答案最好贴在这里:/sf/ask/440592561/ (2认同)

use*_*684 55

您必须设置条件以检查您要搜索的元素是否在列表中

if 'your_element' in mylist:
    print mylist.index('your_element')
else:
    print None
Run Code Online (Sandbox Code Playgroud)

  • 这有助于我们避免 try catch! (2认同)
  • 然而,这可能会使复杂性加倍。有人查过吗? (2认同)
  • @stefanct 时间复杂度仍然是线性的,但它将迭代列表两次。 (2认同)
  • @ApproachingDarknessFish 这显然就是我的意思。即使迂腐地讲,它的复杂性是相同的“顺序”,但在许多用例中迭代两次可能是一个严重的缺点,因此我提出了它。而我们仍然不知道答案...... (2认同)

小智 43

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

[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
Run Code Online (Sandbox Code Playgroud)

如果语言提供了自己想做的方法,为什么要编写一个带异常处理的函数?

  • 第三种方法在列表上迭代两次,对吧? (8认同)

rbr*_*uda 37

如果您想要所有索引,那么您可以使用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),)
Run Code Online (Sandbox Code Playgroud)

它是清晰易读的解决方案.

  • 那么字符串列表,非数字对象列表等等呢? (4认同)
  • 这个答案最好贴在这里:/sf/ask/440592561/ (2认同)

Bab*_*pha 33

me = ["foo", "bar", "baz"]
me.index("bar") 
Run Code Online (Sandbox Code Playgroud)

您可以将其应用于列表中的任何成员来获取他们的索引


Aar*_*all 30

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

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

嗯,当然,有索引方法,它返回第一次出现的索引:

>>> l = ["foo", "bar", "baz"]
>>> l.index('bar')
1
Run Code Online (Sandbox Code Playgroud)

这种方法存在一些问题:

  • 如果值不在列表中,您将得到一个 ValueError
  • 如果列表中有多个值,则只获取第一个值的索引

没有价值

如果价值可能丢失,你需要抓住ValueError.

您可以使用如下可重用的定义来执行此操作:

def index(a_list, value):
    try:
        return a_list.index(value)
    except ValueError:
        return None
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

>>> print(index(l, 'quux'))
None
>>> print(index(l, 'bar'))
1
Run Code Online (Sandbox Code Playgroud)

而这种方法的缺点是,你将可能有一个检查,如果返回值isis not无:

result = index(a_list, value)
if result is not None:
    do_something(result)
Run Code Online (Sandbox Code Playgroud)

列表中有多个值

如果您可能有更多事件,您将无法获得完整信息list.index:

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

您可以枚举列表中的索引:

>>> [index for index, v in enumerate(l) if v == 'bar']
[1, 3]
>>> [index for index, v in enumerate(l) if v == 'boink']
[]
Run Code Online (Sandbox Code Playgroud)

如果没有出现,可以使用布尔检查结果来检查,或者如果循环结果则不执行任何操作:

indexes = [index for index, v in enumerate(l) if v == 'boink']
for index in indexes:
    do_something(index)
Run Code Online (Sandbox Code Playgroud)

更好的数据与熊猫交配

如果您有pandas,可以使用Series对象轻松获取此信息:

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

比较检查将返回一系列布尔值:

>>> series == 'bar'
0    False
1     True
2    False
3     True
dtype: bool
Run Code Online (Sandbox Code Playgroud)

通过下标表示法将该系列布尔值传递给系列,您只得到匹配的成员:

>>> series[series == 'bar']
1    bar
3    bar
dtype: object
Run Code Online (Sandbox Code Playgroud)

如果只需要索引,index属性将返回一系列整数:

>>> series[series == 'bar'].index
Int64Index([1, 3], dtype='int64')
Run Code Online (Sandbox Code Playgroud)

如果你想要它们在列表或元组中,只需将它们传递给构造函数:

>>> list(series[series == 'bar'].index)
[1, 3]
Run Code Online (Sandbox Code Playgroud)

是的,你也可以使用枚举的列表理解,但在我看来,这不是那么优雅 - 你在Python中进行相等的测试,而不是让用C编写的内置代码处理它:

>>> [i for i, value in enumerate(l) if value == 'bar']
[1, 3]
Run Code Online (Sandbox Code Playgroud)

这是XY问题吗?

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

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

如果您已经知道该值,为什么要关注它在列表中的位置?

如果价值不存在,那么抓住它ValueError是相当冗长的 - 我宁愿避免这种情况.

我通常会在列表上进行迭代,所以我通常会指向任何有趣的信息,并使用枚举来获取索引.

如果你正在调整数据,你可能应该使用pandas - 它拥有比我所展示的纯Python工作区更优雅的工具.

我不记得需要list.index,我自己.但是,我查看了Python标准库,我看到了它的一些很好的用途.

idlelibGUI和文本解析有很多很多用途.

keyword模块使用它来查找模块中的注释标记,以通过元编程自动重新生成其中的关键字列表.

在Lib/mailbox.py中,它似乎像有序映射一样使用它:

key_list[key_list.index(old)] = new
Run Code Online (Sandbox Code Playgroud)

del key_list[key_list.index(key)]
Run Code Online (Sandbox Code Playgroud)

在Lib/http/cookiejar.py中,似乎用于下个月:

mon = MONTHS_LOWER.index(mon.lower())+1
Run Code Online (Sandbox Code Playgroud)

在Lib/tarfile.py中类似于distutils来获取切片到项目:

members = members[:members.index(tarinfo)]
Run Code Online (Sandbox Code Playgroud)

在Lib/pickletools.py中:

numtopop = before.index(markobject)
Run Code Online (Sandbox Code Playgroud)

这些用法似乎有共同之处在于它们似乎在约束大小的列表上运行(因为O(n)查找时间很重要list.index),并且它们主要用于解析(以及空闲时的UI).

虽然有用例,但它们并不常见.如果您发现自己正在寻找这个答案,那么问问自己,您所做的事情是否是最直接使用该语言为您的用例提供的工具.


Arn*_*ira 22

具有该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')
Run Code Online (Sandbox Code Playgroud)

  • 这个答案最好贴在这里:/sf/ask/440592561/ (2认同)

Gio*_* PY 21

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

使用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]
>>>
Run Code Online (Sandbox Code Playgroud)

让我们的函数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"))
Run Code Online (Sandbox Code Playgroud)

产量


[1, 3, 5, 7]
Run Code Online (Sandbox Code Playgroud)

简单

for n, i in enumerate([1, 2, 3, 4, 1]):
    if i == 1:
        print(n)
Run Code Online (Sandbox Code Playgroud)

输出:

0
4
Run Code Online (Sandbox Code Playgroud)

  • 这个答案最好贴在这里:/sf/ask/440592561/ (2认同)

Lun*_*D10 19

这是使用 Python 函数的两行代码index()

LIST = ['foo' ,'boo', 'shoo']
print(LIST.index('boo'))
Run Code Online (Sandbox Code Playgroud)

输出:1


kir*_*off 16

你可以随便去

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

res = [[x[0] for x in a].index(y) for y in b]
Run Code Online (Sandbox Code Playgroud)


Mat*_*are 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]
>>> 
Run Code Online (Sandbox Code Playgroud)

  • 这个答案最好贴在这里:/sf/ask/440592561/ (2认同)

MrW*_*ful 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')
Run Code Online (Sandbox Code Playgroud)

粘贴到交互式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]
>>> 
Run Code Online (Sandbox Code Playgroud)

更新

经过另一年的低调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')
Run Code Online (Sandbox Code Playgroud)

其中,当粘贴到交互式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]
>>> 
Run Code Online (Sandbox Code Playgroud)

现在,在回顾了这个问题和所有答案之后,我意识到这正是FMc在他之前的回答中所建议的.当我最初回答这个问题时,我甚至没有看到答案,因为我不明白.我希望我更冗长的例子有助于理解.

如果上面的单行代码对您没有意义,我强烈建议您使用Google"python list comprehension"并花几分钟时间熟悉自己.它只是使用Python开发代码的许多强大功能之一.


bva*_*lew 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]}
>>> 
Run Code Online (Sandbox Code Playgroud)

您也可以将其用作单个班轮来获取单个条目的所有索引.虽然我确实使用set(a)来减少lambda被调用的次数,但是效率没有保证.

  • 这个答案应该更好地发布在这里:/sf/ask/440592561/ (2认同)

Kof*_*ofi 11

列表理解将是在查找列表中项目的索引时获得紧凑实现的最佳选择。

a_list = ["a", "b", "a"]
print([index for (index , item) in enumerate(a_list) if item == "a"])
Run Code Online (Sandbox Code Playgroud)


dyl*_*nkb 10

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

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


Gia*_*dei 8

它仅使用 python 函数array.index()和一个简单的 Try / except,如果在列表中找到记录,则返回记录的位置;如果在列表中未找到记录,则返回 -1(就像 JavaScript 上的函数indexOf())。

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

try:
  pos = fruits.index("mango")
except:
  pos = -1
Run Code Online (Sandbox Code Playgroud)

在这种情况下,列表中不存在“mango” fruits,因此pos变量为 -1,如果我搜索“cherry”,则pos变量将为 2。


Ank*_*pta 7

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

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

更通用的形式:

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


Ket*_*tan 7

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

idx = L.index(x) if (x in L) else -1
Run Code Online (Sandbox Code Playgroud)

  • 这会使阵列重复两次,因此可能导致大型阵列的性能问题。 (4认同)

Cav*_*man 7

对于一个可比的

# Throws ValueError if nothing is found
some_list = ['foo', 'bar', 'baz'].index('baz')
# some_list == 2
Run Code Online (Sandbox Code Playgroud)

自定义谓词

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())
Run Code Online (Sandbox Code Playgroud)

通过谓词查找所有项目的索引

index_of_staff_members = [
    i for i, user in enumerate(users)
    if user.is_staff()]
Run Code Online (Sandbox Code Playgroud)


Ham*_*our 6

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

try:
    index = array.index('search_keyword')
except ValueError:
    index = -1
Run Code Online (Sandbox Code Playgroud)

  • 然而,_JavaScript_ 的理念是奇怪的结果比错误更好,因此返回 -1 是有意义的,但在 Python 中,它可能会造成难以追踪的错误,因为 -1 从列表末尾返回一个项目。 (7认同)

小智 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)
Run Code Online (Sandbox Code Playgroud)

这说明字符串是否也不在列表中,如果它不在列表中,则location = -1


小智 5

由于Python列表从零开始,我们可以使用zip内置函数,如下所示:

>>> [i for i,j in zip(range(len(haystack)), haystack) if j == 'needle' ]
Run Code Online (Sandbox Code Playgroud)

其中"haystack"是有问题的列表,"needle"是要查找的项目.

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

  • [i for i,j in enumerate(haystack)如果j =='needle']更紧凑和可读,我想. (3认同)

Fat*_*ici 5

如果关注性能:

很多答案都提到method的内置方法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.
Run Code Online (Sandbox Code Playgroud)

如果您可能有重复的元素,并且需要返回它们的所有索引:

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]
Run Code Online (Sandbox Code Playgroud)


Vla*_*den 5

如果您要查找一次索引,那么使用“index”方法就可以了。但是,如果您要多次搜索数据,那么我建议使用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}")
Run Code Online (Sandbox Code Playgroud)

输出:

t1=0.0400, t2=0.0020, diffs t1/t2=19.60
Run Code Online (Sandbox Code Playgroud)


Bad*_*del 5

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


MD *_*YON 5

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

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


Run Code Online (Sandbox Code Playgroud)