问题描述:
给定一个列表 [“foo”, “bar”, “baz”] 和列表 “bar” 中的一个项目,我如何获得它的索引 1?
解决方案1:
保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com
>>> ["foo", "bar", "baz"].index("bar")
1
参考:Data Structures > More on Lists
警告如下
请注意,虽然这可能是回答问题的最简洁的方法按要求,但 index 是 list API 的一个相当薄弱的组件,我不记得我上次使用它是什么时候了在愤怒中。评论中已向我指出,由于此答案被大量引用,因此应使其更加完整。以下是关于 list.index 的一些注意事项。最初可能值得看一下它的文档:
list.index(x[, start[, end]]) 返回值等于 x 的第一项的列表中从零开始的索引。如果没有此类项目,则引发 ValueError。可选参数 start 和 end 被解释为切片符号,用于将搜索限制为列表的特定子序列。返回的索引是相对于完整序列的开头而不是 start 参数计算的。
列表长度的线性时间复杂度
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
仅将第一个匹配项的索引返回到其参数
对 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
在我曾经使用 index 的大多数地方,我现在使用列表推导式或生成器表达式,因为它们更通用。因此,如果您正在考虑使用 index,请查看这些出色的 Python 功能。
如果元素不存在于列表中,则抛出
如果项目不存在,则调用 index 会导致 ValueError。
>>> [1, 1].index(2)
Traceback (most recent call last):
File "", line 1, in
ValueError: 2 is not in list
如果该项目可能不在列表中,您应该
首先使用 my_list 中的项目检查它(干净,可读的方法),或者将索引调用包装在捕获 ValueError 的 try/except 块中(可能更快,至少当要搜索的列表很长并且项目通常存在时。 )
index 返回值为“bar”的第一项。如果“bar”在列表中存在两次,您将永远找不到第二个“bar”的键。请参阅文档:docs.python.org/3/tutorial/datastructures.html
如果您只搜索一个元素(第一个),我发现 index() 比针对整数列表的列表理解快 90%。
如果列表很长,应该使用什么数据结构?
@izhang:一些辅助索引,例如 {element -> list_index} 字典,如果元素是可散列的,并且列表中的位置很重要。
sequence1 = sorted(sequence2, key=.sequence3.index) 是一个非常方便的习语。如果您的曲目中有索引,您可能会更频繁地使用它。
解决方案2:
huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式
对学习 Python 真正有帮助的一件事是使用交互式帮助功能:
>>> help(["foo", "bar", "baz"])
Help on list object:
class list(object)
...
|
| index(...)
| L.index(value, [start, [stop]]) -> integer -- return first index of value
|
这通常会引导您找到您正在寻找的方法。
bpython 是一种以交互方式阅读文档的用户友好方式。
@davidavr 是的,但是我们其他只想用谷歌搜索它而不是滚动浏览帮助文档的人不会有这么好的、中心的、排名的选项集。 :)
解决方案3:
一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会
大多数答案解释了如何找到单个索引,但如果项目多次出现在列表中,它们的方法不会返回多个索引。使用 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
对我来说,枚举比基于索引的方法效果更好,因为我希望使用 'startswith" 来收集字符串的索引,并且我需要收集多次出现的情况。或者有没有一种方法可以将索引与“startswith”一起使用,我想不通
在我手中,枚举版本始终稍快一些。自上述测量发布以来,一些实施细节可能已经改变。
自 11 年以来已经回答了这个问题:stackoverflow.com/questions/6294179/…
解决方案4:
与HuntsBot一起,探索全球自由职业机会–huntsbot.com
获取所有索引:
indexes = [i for i,x in enumerate(xs) if x == 'foo']
huntsbot.com聚合了超过10+全球外包任务平台的外包需求,寻找外包任务与机会变的简单与高效。
在 '11 中添加了另一个问题:stackoverflow.com/questions/6294179/…
解决方案5:
huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求
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"])
如果列表中不存在?
不存在的项目将引发 ValueError
这个答案更适合这里:stackoverflow.com/questions/6294179/…
解决方案6:
打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!
如果该元素不在列表中,则会出现问题。这个函数处理这个问题:
# 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
解决方案7:
与HuntsBot一起,探索全球自由职业机会–huntsbot.com
a = ["foo","bar","baz",'bar','any','much']
indexes = [index for index in range(len(a)) if a[index] == 'bar']
解决方案8:
与HuntsBot一起,探索全球自由职业机会–huntsbot.com
您必须设置一个条件来检查您正在搜索的元素是否在列表中
if 'your_element' in mylist:
print mylist.index('your_element')
else:
print None
这有助于我们避免尝试捕获!
但是,它可能会使复杂性加倍。有人检查吗?
@stefanct 时间复杂度仍然是线性的,但它会遍历列表两次。
@ApproachingDarknessFish 这显然是我的意思。即使从迂腐的角度来看,它的复杂性是相同的,但在许多用例中迭代两次可能是一个严重的劣势,因此我提出了它。而我们仍然不知道答案...
@stefanct 这可能会使复杂性加倍,我相信列表上的 in 运算符具有线性运行时。 @ApproachingDarknessFish 表示它会迭代两次以回答您的问题,并且正确地说将线性复杂度加倍并不是什么大问题。在许多用例中,我不会将迭代列表两次称为严重劣势,因为复杂性理论告诉我们 O(n) + O(n) -> O(2*n) -> O(n),即变化通常可以忽略不计。
解决方案9:
huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。
如果您想要所有索引,则可以使用 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),)
这是清晰易读的解决方案。
字符串列表、非数字对象列表等呢?
这个答案应该更好地发布在这里:stackoverflow.com/questions/6294179/…
这是我读过的最好的一本。 numpy 数组比 Python 列表高效得多。如果列表很短,那么从 Python 列表中复制它是没有问题的,如果不是,那么也许开发人员应该首先考虑将元素存储在 numpy 数组中。
解决方案10:
一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会
这里提出的所有功能都重现了固有的语言行为,但掩盖了正在发生的事情。
[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
如果语言提供了执行您想要的方法的方法,为什么还要编写带有异常处理的函数?
第三种方法在列表上迭代两次,对吗?
回复:“这里提出的所有功能”:可能在撰写本文时,但您应该检查更新的答案,看看它是否仍然正确。
解决方案11:
打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!
在 Python 中查找给定包含它的列表的项目的索引对于列表 [“foo”、“bar”、“baz”] 和列表“bar”中的项目,获取其索引的最简洁方法是什么 (1)在 Python 中?
好吧,当然,有 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
这样做的缺点是您可能会检查返回值是 is 还是 is not None:
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 更好地处理数据
如果您有 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]
是的,您也可以将列表推导与 enumerate 一起使用,但在我看来,这并不那么优雅 - 您正在 Python 中进行相等性测试,而不是让用 C 编写的内置代码来处理它:
>>> [i for i, value in enumerate(l) if value == 'bar']
[1, 3]
这是XY问题吗?
XY 问题是询问您尝试的解决方案,而不是您的实际问题。
为什么你认为你需要给定列表中的元素的索引?
如果您已经知道该值,为什么还要关心它在列表中的位置?
如果该值不存在,则捕获 ValueError 相当冗长 - 我更愿意避免这种情况。
无论如何,我通常会遍历列表,所以我通常会保留指向任何有趣信息的指针,获取 index with enumerate.
如果您正在处理数据,您可能应该使用 pandas - 它拥有比我展示的纯 Python 解决方法更优雅的工具。
我自己不记得需要list.index。但是,我浏览了 Python 标准库,发现它有一些出色的用途。
在 idlelib 中有很多很多用途,用于 GUI 和文本解析。
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)
这些用法的共同点似乎是它们似乎在限制大小的列表上运行(很重要,因为 list.index 的 O(n) 查找时间),并且它们主要用于解析(以及 UI 在闲置的)。
虽然有它的用例,但它们并不常见。如果您发现自己正在寻找这个答案,请问问自己,您所做的是否是该语言为您的用例提供的工具的最直接使用。
原文链接:https://www.huntsbot.com/qa/yObA/finding-the-index-of-an-item-in-a-list?lang=zh_CN
huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求