查找列表中项目的索引

新手上路,请多包涵

给定一个列表 ["foo", "bar", "baz"] 和列表中的一个项目 "bar" ,我如何获得它的索引 1

原文由 Eugene M 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 851
2 个回答
>>> ["foo", "bar", "baz"].index("bar")
1

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

警告如下

请注意,虽然这可能是回答所 问题的最干净的方法,但 indexlist API 的一个相当弱的组件,我不记得我上次使用的时间它在愤怒中。评论中已向我指出,由于此答案被大量引用,因此应使其更加完整。关于 list.index 的一些警告如下。最初可能值得看一下它的文档:

>  list.index(x[, start[, end]])
>
> ```
>
> 返回值等于 _x_ 的第一项的列表中从零开始的索引。如果没有这样的项目,则引发 [`ValueError`](https://docs.python.org/library/exceptions.html#ValueError) 。
>
> 可选参数 _start_ 和 _end_ 被解释为 [切片符号](https://docs.python.org/tutorial/introduction.html#lists),用于将搜索限制为列表的特定子序列。返回的索引是相对于完整序列的开头而不是 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`](https://docs.python.org/library/exceptions.html#ValueError) 。

[1, 1].index(2) Traceback (most recent call last): File “”, line 1, in ValueError: 2 is not in list

”`

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

  1. 首先使用 item in my_list (干净,可读的方法)检查它,或者
  2. index 调用包装在 --- try/except 块中,该块捕获 ValueError (可能更快,至少在要搜索的列表很长并且该项目通常存在时。 )

原文由 Alex Coventry 发布,翻译遵循 CC BY-SA 4.0 许可协议

大多数答案都解释了如何找到 单个索引,但是如果该项目多次出现在列表中,他们的方法不会返回多个索引。使用 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() 的另一个小解决方案(与枚举的方法几乎相同):

 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

原文由 TerryA 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题