在 Python 中给定包含该项目的列表的情况下查找项目的索引

对于列表["foo", "bar", "baz"]和列表"bar" ,如何在 Python 中获取其索引(1)?

答案

>>> ["foo", "bar", "baz"].index("bar")
1

参考: 数据结构 > 列表中的更多内容

注意事项

请注意,虽然这也许是回答, 因为问的问题最彻底的方法, index是一个相当薄弱的组件list API,我不记得我最后一次使用它的愤怒。在评论中已向我指出,由于此答案被大量引用,因此应使其更完整。有关list.index一些警告。可能值得一开始看看它的文档字符串:

>>> print(list.index.__doc__)
L.index(value, [start, [stop]]) -> integer -- return first index of value.
Raises ValueError if the value is not present.

列表长度的线性时间复杂度

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 "<stdin>", line 1, in <module>
ValueError: 2 is not in list

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

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

学习 Python 真正有用的一件事是使用交互式帮助功能:

>>> help(["foo", "bar", "baz"])
Help on list object:

class list(object)
 ...

 |
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value
 |

这通常会引导您找到所需的方法。

大多数答案都说明了如何查找单个索引 ,但是如果该项在列表中多次,则它们的方法不会返回多个索引。使用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()另一个小解决方案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

要获取所有索引:

indexes = [i for i,x in enumerate(xs) if x == 'foo']

index()返回值的第一个索引!

| 指数(...)
| L.index(value,[start,[stop]])-> 整数 - 返回值的第一个索引

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"])

如果该元素不在列表中,则会出现问题。此函数可解决此问题:

# 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
a = ["foo","bar","baz",'bar','any','much']

indexes = [index for index in range(len(a)) if a[index] == 'bar']

您必须设置条件以检查要搜索的元素是否在列表中

if 'your_element' in mylist:
    print mylist.index('your_element')
else:
    print None

此处提出的所有功能均会重现固有的语言行为,但会掩盖正在发生的事情。

[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

如果该语言提供了执行所需功能的方法,为什么还要编写具有异常处理功能的函数?

如果需要所有索引,则可以使用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),)

这是一个清晰易读的解决方案。