如何获取列表["foo", "bar", "baz"]
中元素"bar"
的索引1
?
>>> ["foo", "bar", "baz"].index("bar")
1
请查看文档,了解列表的内置.index()
方法:
list.index(x[, start[, end]])
Return zero-based index in the list of the first item whose value is equal to x. Raises a
ValueError
if there is no such item.The optional arguments start and end are interpreted as in the slice notation and are used to limit the search to a particular subsequence of the list. The returned index is computed relative to the beginning of the full sequence rather than the start argument.
index
调用按顺序检查列表的每个元素,直到找到匹配项。如果列表很长,并且没有保证值靠近开头,这可能会减慢代码速度。
只能通过使用不同的数据结构完全避免此问题。但是,如果已知要素位于列表的某个部分中,则可以使用 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
index
会按顺序在列表中搜索,直到找到匹配项,并在那里停止。如果该值可能有多个出现位置并且需要所有索引,则index
无法解决问题:>>> [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
item in my_list
进行显式检查,或者根据需要使用try
/except
处理异常。 显式检查简单易懂,但必须再次迭代列表。有关此选择的更多指导,请参见Python中的EAFP原则是什么?。index()
函数比用列表推导式在整数列表中进行查找快了将近90%。 - slybloty大多数答案都解释了如何找到单个索引,但是如果该项在列表中出现多次,则它们的方法不会返回多个索引。使用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
if len([i for i, j in enumerate(['foo', 'bar', 'baz']) if j == 'bar']) > 1
,否则您可以返回[i for i, j in enumerate(['foo', 'bar', 'baz']) if j == 'bar'][0]
。 - Brian Keith要获取所有的索引:
indexes = [i for i, x in enumerate(xs) if x == 'foo']
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"])
a = ["foo","bar","baz",'bar','any','much']
indexes = [index for index in range(len(a)) if a[index] == 'bar']
如果元素不在列表中,将会出现问题。这个函数处理此问题:
# 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
if 'your_element' in mylist:
print mylist.index('your_element')
else:
print None
如果你想要所有索引,你可以使用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),)
这是一个清晰易读的解决方案。
对于一个列表 ["foo", "bar", "baz"]
并且该列表中有一项 "bar"
,最简洁的方法是什么来获取它的索引(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
这样做的缺点是你可能需要检查返回值 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,可以使用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问题是指询问关于您尝试解决的问题而不是您实际问题本身。
你觉得你需要列表中元素的索引吗?
如果你已经知道了值,你为什么要在列表中找到它的位置呢?
如果该值不存在,则捕获ValueError
会非常繁琐 - 我倾向于避免这种情况。
我通常都在迭代列表,所以我通常会保留任何有趣信息的指针,并使用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)]
numtopop = before.index(markobject)
list.index
的O(n)查找时间而很重要),并且它们在解析中被广泛使用(在Idle的情况下也包括UI)。这里提出的所有功能都能够重现内在的语言行为,但会掩盖正在发生的事情。
[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
如果编程语言本身提供了所需的方法,为什么还要编写带有异常处理的函数呢?
"bar"
实例,则返回最低的索引, [2] 所有"bar"
的索引? - Ṃųỻịgǻňạcểơửṩ