给定一个列表[“foo”、“bar”、“baz”]和列表“bar”中的一个项,如何获取其索引1?


当前回答

不要。如果您确实需要,请使用列表中的.index(item…)方法。然而,这需要线性的时间,如果你发现自己正在努力,你可能会滥用列表来做一些你不应该做的事情。

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

对于第一个,使用一对字典。如果您需要一个库来实现这一点,请使用双向库。

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

如果您希望在排序列表中插入项目,也不应使用排序列表。使用内置的heapq模块或使用sortedcontainers库将已排序的需求弱化为堆。

使用一个不是为你想做的事情而设计的数据结构是不好的做法。使用一个与你给它的任务相匹配的数据结构,既会向读者传达你想做特定的事情,也会使你的解决方案在实践中更快/更具可扩展性。

其他回答

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

try:
    index = array.index('search_keyword')
except ValueError:
    index = -1

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

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

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

参考文献:

在列表中

在元组中

字符串中

如果性能令人担忧:

在许多答案中都提到,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]

如果你想找到一个索引,那么使用“index”方法就可以了。然而,如果您要多次搜索数据,那么我建议使用平分模块。请记住,使用平分模块数据必须进行排序。因此,您对数据进行一次排序,然后可以使用二等分。在我的机器上使用平分模块比使用索引方法快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