在Python中给定一个包含某项内容的列表,寻找该项内容的索引

对于一个列表["foo", "bar", "baz"]和列表中的一个项目"bar",我如何在Python中得到它的索引(1)?

对该问题的评论 (2)
解决办法
>>> ["foo", "bar", "baz"].index("bar")
1

参考资料。Data Structures > More on Lists

注意事项如下

请注意,虽然这可能是回答这个问题的最干净的方法,但 "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 "", line 1, in 
ValueError: 2 is not in list

如果该项目可能不存在于列表中,你应该选择

1.先用item in my_list检查它(干净、可读的方法),或者 2.将index'调用包裹在一个try/except'块中,该块可以捕获`ValueError'(可能更快,至少当要搜索的列表很长,并且项目通常是存在的)。

评论(2)

在学习Python的过程中,有一件事真的很有帮助,就是使用交互式帮助功能。

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

class list(object)
 ...

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

这通常会引导你找到你要找的方法。

评论(1)

大多数答案都解释了如何找到个单一的索引,但如果项目在列表中多次出现,它们的方法就不会返回多个索引。 使用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
评论(3)

要获取所有索引。

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

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

| 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"])
评论(3)

如果元素不在列表中,就会出现问题。 这个函数可以处理这个问题。

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

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

你必须设置一个条件来检查你正在搜索的元素是否在列表中。

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

这里提出的所有功能都重现了固有的语言行为,但却掩盖了'发生了什么。

[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

如果语言自己提供方法来做你想要的事情,为什么要写一个带有异常处理的函数呢?

评论(2)

如果你想要所有的索引,那么你可以使用 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),)

它是清晰的、可读的解决方案。

1:

评论(2)

在Python中查找包含一个列表的项的索引。

对于一个列表["foo", "bar", "baz"]和列表中的一个项目"bar",在Python中获取其索引(1)的最简洁的方法是什么?

嗯,当然,有'的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

这样做的缺点是,你可能需要检查返回的值是还是不是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)

用大熊猫更好地进行数据挖掘。

如果你有熊猫,你可以很容易地通过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

如果你只想要索引,索引属性会返回一系列的整数。

>>> series[series == 'bar'].index
Int64Index([1, 3], dtype='int64')

如果你想把它们放在一个 list 或 tuple 中,只需把它们传递给构造函数即可。

>>> list(series[series == 'bar'].index)
[1, 3]

是的,你也可以用枚举来理解列表,但在我看来,这并不优雅--你在 Python 中做平等性测试,而不是让 C 语言中的内置代码来处理它。

>>> [i for i, value in enumerate(l) if value == 'bar']
[1, 3]

##这是一个XY问题

XY问题问的是你的尝试性解决方案,而不是你的实际问题。

为什么你认为你需要列表中元素的索引?

如果你已经知道了这个值,为什么还要关心它在列表中的位置?

如果值不在那里,捕捉ValueError是相当啰嗦的--我更喜欢避免这样。

无论如何,我通常会在列表上迭代,所以我通常会保留一个指针,指向任何有趣的信息,得到[index with enumerate.][2] 。

如果你正在进行数据挖掘,你可能应该使用 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),所以很重要),而且它们'主要用于解析(和Idle的UI)。

虽然也有用例,但相当不常见。 如果你发现自己在寻找这个答案,问问自己,你所做的是否是语言为你的用例提供的工具的最直接用法。

1:

[2]: https://stackoverflow.com/q/522563/541136

评论(0)

所有使用[zip][1]函数的索引。

get_indexes = lambda x, xs: [i for (y, i) in zip(xs, range(len(xs))) if x == y]

print get_indexes(2, [1, 2, 3, 4, 5, 6, 3, 2, 3, 2])
print get_indexes('f', 'xsfhhttytffsafweef')

[1]: https://docs.python.org/2/library/functions.html#zip

评论(1)

获取列表中一个或多个(相同)项目的所有出现次数和位置。

使用enumerate(alist)可以存储第一个元素(n),当元素x等于你所寻找的元素时,它就是列表的索引。

>>> alist = ['foo', 'spam', 'egg', 'foo']
>>> foo_indexes = [n for n,x in enumerate(alist) if x=='foo']
>>> foo_indexes
[0, 3]
>>>

Let's使我们的函数findindex

这个函数将 item 和 list 作为参数,并返回 item 在 list 中的位置,就像我们之前看到的那样。

def indexlist(item2find, list_or_string):
  "Returns all indexes of an item in a list or a string"
  return [n for n,item in enumerate(list_or_string) if item==item2find]

print(indexlist("1", "010101010"))

产出


[1, 3, 5, 7]

简单

for n, i in enumerate([1, 2, 3, 4, 1]):
    if i == 1:
        print(n)

产出:

0
4
评论(1)

另一种选择

>>> a = ['red', 'blue', 'green', 'red']
>>> b = 'red'
>>> offset = 0;
>>> indices = list()
>>> for i in range(a.count(b)):
...     indices.append(a.index(b,offset))
...     offset = indices[-1]+1
... 
>>> indices
[0, 3]
>>> 
评论(1)

简单的你可以选择

a = [['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']]
b = ['phone', 'lost']

res = [[x[0] for x in a].index(y) for y in b]
评论(0)

而现在,对于完全不同的东西... ...

... 比如在获取索引之前确认项目的存在。 这种方法的好处是函数总是返回一个索引列表--即使它是一个空列表。 它也适用于字符串。
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]
>>> 

Update

在经历了一年的低头开发python之后,我对自己最初的答案感到有些尴尬,所以为了澄清事实,当然可以使用上面的代码,然而,更习以为常的方法是使用list comprehension,以及enumerate(函数)。 但是,要想得到同样的行为,多的方法是使用list comprehension,以及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]
>>> 

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][1]在他的[早期答案][2]中所建议的。 在我最初回答这个问题的时候,我甚至没有看到*那个答案,因为我没有理解它。 我希望我这个有点啰嗦的例子能帮助大家理解。

如果上面的单行代码对你来说仍然是*没有意义的,我强烈建议你在Google上搜索'python list comprehension&#39。 并花几分钟时间熟悉一下。 它只是众多强大功能中的一个,它使使用Python开发代码成为一种乐趣。

[1]: https://stackoverflow.com/users/55857/fmc [2]: https://stackoverflow.com/questions/176918/finding-the-index-of-an-item-given-a-list-containing-it-in-python/17300987#17300987

评论(0)

FMc 和 user7177 的答案的一个变体将给出一个可以返回任何条目的所有索引的 dict。

>>> a = ['foo','bar','baz','bar','any', 'foo', 'much']
>>> l = dict(zip(set(a), map(lambda y: [i for i,z in enumerate(a) if z is y ], set(a))))
>>> l['foo']
[0, 5]
>>> l ['much']
[6]
>>> l
{'baz': [2], 'foo': [0, 5], 'bar': [1, 3], 'any': [4], 'much': [6]}
>>> 

你也可以把它作为一个单行线来获取一个条目的所有指数。 虽然我使用了set(a)来减少lambda的调用次数,但不能保证效率。

评论(1)

这个解决方案没有其他解决方案那么强大,但如果你是初学者,只知道 "for "循环,还是可以在避免ValueError的同时找到一个项目的第一个索引。

def find_element(p,t):
    i = 0
    for e in p:
        if e == t:
            return i
        else:
            i +=1
    return -1
评论(0)

寻找列表L中x项的索引。

idx = L.index(x) if (x in L) else -1
评论(2)
name ="bar"
list = [["foo", 1], ["bar", 2], ["baz", 3]]
new_list=[]
for item in list:
    new_list.append(item[0])
print(new_list)
try:
    location= new_list.index(name)
except:
    location=-1
print (location)

这也说明了如果字符串不在列表中,如果它不在列表中,那么location = -1

评论(0)