给定一个列表[“foo”、“bar”、“baz”]和列表“bar”中的一个项,如何获取其索引1?
当前回答
python中的某些结构包含一个索引方法,可以很好地解决这个问题。
'oi tchau'.index('oi') # 0
['oi','tchau'].index('oi') # 0
('oi','tchau').index('oi') # 0
参考文献:
在列表中
在元组中
字符串中
其他回答
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
me = ["foo", "bar", "baz"]
me.index("bar")
您可以将此应用于列表中的任何成员以获取其索引
现在,对于完全不同的事情。。。
……比如在获取索引之前确认项目的存在。这种方法的好处是,函数总是返回一个索引列表——即使它是一个空列表。它也适用于字符串。
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开发代码成为一件乐事。
>>> ["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安装。
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用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中获得所有直接子目录