给定一个列表[“foo”、“bar”、“baz”]和列表“bar”中的一个项,如何获取其索引1?
当前回答
text = ["foo", "bar", "baz"]
target = "bar"
[index for index, value in enumerate(text) if value == target]
对于一个小的元素列表,这会很好。但是,如果列表包含大量元素,最好应用二进制运行时复杂度为O(logn)的搜索.
其他回答
简单选项:
a = ["foo", "bar", "baz"]
[i for i in range(len(a)) if a[i].find("bar") != -1]
如果找不到项,Python index()方法将抛出错误。因此,您可以将其设置为类似于JavaScript的indexOf()函数,如果未找到项,则返回-1:
try:
index = array.index('search_keyword')
except ValueError:
index = -1
>>> ["foo", "bar", "baz"].index("bar")
1
有关列表的内置.index()方法,请参阅文档:
list.index(x[,start[,end]])返回值等于x的第一项列表中从零开始的索引。如果没有该项,则引发ValueError。可选参数start和end被解释为切片符号,用于将搜索限制在列表的特定子序列。返回的索引是相对于完整序列的开头而不是start参数计算的。
注意事项
列表长度的线性时间复杂性
索引调用按顺序检查列表中的每个元素,直到找到匹配项。如果列表很长,并且不能保证值会接近开始,这会降低代码的速度。
只有使用不同的数据结构才能完全避免这个问题。但是,如果已知元素在列表的某个部分内,则可以使用start和end参数来缩小搜索范围。
例如:
>>> 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万个元素。
仅返回第一个匹配项的索引
对索引的调用按顺序搜索列表,直到找到匹配项,然后停止。如果该值可能出现多次,并且需要所有索引,则索引无法解决问题:
>>> [1, 1].index(1) # the `1` index is not found.
0
相反,使用列表理解或生成器表达式进行搜索,使用enumerate获取索引:
>>> # 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
如果只有一个匹配项,列表理解和生成器表达式技术仍然有效,并且更具通用性。
如果不匹配,则引发异常
如以上文档中所述,如果搜索的值不在列表中,则使用.index将引发异常:
>>> [1, 1].index(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: 2 is not in list
如果这是一个问题,请首先使用my_list中的项显式检查,或者根据需要使用try/except处理异常。
显式检查简单易读,但它必须再次迭代列表。参见Python中的EAFP原理是什么?以获取有关此选择的更多指导。
正如@TerryA所指出的,许多答案讨论了如何找到一个索引。
moreintertools是一个第三方库,它提供了在可迭代文件中查找多个索引的工具。
鉴于
import more_itertools as mit
iterable = ["foo", "bar", "baz", "ham", "foo", "bar", "baz"]
Code
查找多个观测值的索引:
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安装。
text = ["foo", "bar", "baz"]
target = "bar"
[index for index, value in enumerate(text) if value == target]
对于一个小的元素列表,这会很好。但是,如果列表包含大量元素,最好应用二进制运行时复杂度为O(logn)的搜索.
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录