对于列表["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 "", line 1, in ValueError: 2 is not in list
如果该项目可能不在列表中,您应该
首先检查它item in my_list
(干净,可读的方法),或
将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()
(与枚举几乎相同):
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()
返回第一个值的索引!
| 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"])
如果元素不在列表中,则会出现问题.此函数处理问题:
# 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),)
它是清晰易读的解决方案.
在Python中查找包含它的列表的项目的索引
对于列表
["foo", "bar", "baz"]
和列表中的项目,"bar"
在Python中获取其索引(1)的最简洁方法是什么?
嗯,当然,有索引方法,它返回第一次出现的索引:
>>> 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
无:
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]
是的,你也可以使用枚举的列表理解,但在我看来,这不是那么优雅 - 你在Python中进行相等的测试,而不是让用C编写的内置代码处理它:
>>> [i for i, value in enumerate(l) if value == 'bar'] [1, 3]
XY问题是询问您尝试的解决方案而不是实际问题.
为什么你认为你需要给定列表中的元素的索引?
如果您已经知道该值,为什么要关注它在列表中的位置?
如果价值不存在,那么抓住它ValueError
是相当冗长的 - 我宁愿避免这种情况.
我通常会在列表上进行迭代,所以我通常会指向任何有趣的信息,并使用枚举来获取索引.
如果你正在调整数据,你可能应该使用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)
这些用法似乎有共同之处在于它们似乎在约束大小的列表上运行(因为O(n)查找时间很重要list.index
),并且它们主要用于解析(以及空闲时的UI).
虽然有用例,但它们并不常见.如果您发现自己正在寻找这个答案,那么问问自己,您所做的事情是否是最直接使用该语言为您的用例提供的工具.
具有该zip
功能的所有索引:
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')
使用enumerate(alist),当元素x等于您查找的内容时,您可以存储第一个元素(n),该元素是列表的索引.
>>> alist = ['foo', 'spam', 'egg', 'foo'] >>> foo_indexes = [n for n,x in enumerate(alist) if x=='foo'] >>> foo_indexes [0, 3] >>>
此函数将项目和列表作为参数,并返回列表中项目的位置,就像我们之前看到的那样.
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
你可以随便去
a = [['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']] b = ['phone', 'lost'] res = [[x[0] for x in a].index(y) for y in b]
另外一个选项
>>> 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] >>>
...比如在获得索引之前确认项目的存在.这种方法的好处是函数总是返回一个索引列表 - 即使它是一个空列表.它也适用于字符串.
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] >>>更新
经过另一年的低调python开发,我对我的原始答案感到有点尴尬,所以为了直接设置记录,你当然可以使用上面的代码; 然而,很多更地道的方式来获得相同的行为是使用列表理解,用枚举()函数一起.
像这样的东西:
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] >>>
现在,在回顾了这个问题和所有答案之后,我意识到这正是FMc在他之前的回答中所建议的.当我最初回答这个问题时,我甚至没有看到答案,因为我不明白.我希望我更冗长的例子有助于理解.
如果上面的单行代码对您没有意义,我强烈建议您使用Google"python list comprehension"并花几分钟时间熟悉自己.它只是使用Python开发代码的许多强大功能之一.
来自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被调用的次数,但是效率没有保证.
这个解决方案没有其他解决方案那么强大,但是如果你是初学者并且只知道for
循环,那么仍然可以在避免ValueError的同时找到项目的第一个索引:
def find_element(p,t): i = 0 for e in p: if e == t: return i else: i +=1 return -1
在列表L中查找项目x的索引:
idx = L.index(x) if (x in L) else -1
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
由于Python列表从零开始,我们可以使用zip内置函数,如下所示:
>>> [i for i,j in zip(range(len(haystack)), haystack) if j == 'needle' ]
其中"haystack"是有问题的列表,"needle"是要查找的项目.
(注意:这里我们使用i来迭代获取索引,但如果我们需要关注项目,我们可以切换到j.)