对于列表
1 2 | >>> ["foo","bar","baz"].index("bar") 1 |
参考文献:数据结构>更多关于列表
警告遵循
请注意,虽然这可能是回答所问问题的最干净的方法,但
1 2 3 | >>> print(list.index.__doc__) L.index(value, [start, [stop]]) -> integer -- return first index of value. Raises ValueError if the value is not present. |
线性时间复杂度,列表长度
1 2 3 4 5 | >>> 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 |
只返回第一个匹配的索引到它的参数
对
1 2 3 4 5 6 7 8 9 | >>> [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 |
在我曾经使用
如果项目不存在,则调用
1 2 3 4 | >>> [1, 1].index(2) Traceback (most recent call last): File"<stdin>", line 1, in <module> ValueError: 2 is not in list |
如果项目可能不在列表中,您也应该这样做
首先使用在学习Python时,有一件事非常有用,那就是使用交互式帮助函数:
1 2 3 4 5 6 7 8 9 10 | >>> help(["foo","bar","baz"]) Help on list object: class list(object) ... | | index(...) | L.index(value, [start, [stop]]) -> integer -- return first index of value | |
这通常会引导您找到您正在寻找的方法。
大多数答案都解释了如何查找单个索引,但是如果条目多次出现在列表中,它们的方法不会返回多个索引。使用
1 2 3 | for i, j in enumerate(['foo', 'bar', 'baz']): if j == 'bar': print(i) |
函数只返回第一个事件,而
作为一个列表理解:
1 | [i for i, j in enumerate(['foo', 'bar', 'baz']) if j == 'bar'] |
这里还有一个小的解决方案与
1 2 | from itertools import izip as zip, count # izip for maximum efficiency [i for i, j in zip(count(), ['foo', 'bar', 'baz']) if j == 'bar'] |
这对于较大的列表比使用
1 2 3 4 | $ 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 |
获取所有索引:
1 | indexes = [i for i,x in enumerate(xs) if x == 'foo'] |
| index(...)
| L.index(value, [start, [stop]]) -> integer -- return first index of value
1 2 3 4 5 6 7 8 9 10 11 12 | 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"]) |
如果元素不在列表中,就会出现问题。这个函数处理的问题:
1 2 3 4 5 6 7 8 | # 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 |
1 2 3 | a = ["foo","bar","baz",'bar','any','much'] indexes = [index for index in range(len(a)) if a[index] == 'bar'] |
您必须设置一个条件来检查正在搜索的元素是否在列表中
1 2 3 4 | if 'your_element' in mylist: print mylist.index('your_element') else: print None |
这里提出的所有函数都重现了固有的语言行为,但都模糊了正在发生的事情。
1 2 3 4 5 | [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:
1 2 3 4 5 6 7 8 | 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),) |
这是一个清晰易读的解决方案。
Finding the index of an item given a list containing it in Python For a list
["foo","bar","baz"] and an item in the list"bar" , what's the cleanest way to get its index (1) in Python?
当然,有index方法,它返回第一次出现的索引:
1 2 3 | >>> l = ["foo","bar","baz"] >>> l.index('bar') 1 |
这种方法有几个问题:
如果该值不在列表中,您将得到没有值
如果该值可能丢失,则需要捕获
你可以这样使用一个可重用的定义:
1 2 3 4 5 | def index(a_list, value): try: return a_list.index(value) except ValueError: return None |
像这样使用:
1 2 3 4 | >>> print(index(l, 'quux')) None >>> print(index(l, 'bar')) 1 |
这样做的缺点是,您可能会检查返回值
1 2 3 | result = index(a_list, value) if result is not None: do_something(result) |
>列表中的多个值
如果你可以有更多的发生,你不会得到完整的信息与
1 2 3 4 5 | >>> l.append('bar') >>> l ['foo', 'bar', 'baz', 'bar'] >>> l.index('bar') # nothing at index 3? 1 |
你可以列举出一个列表来理解索引:
1 2 3 4 | >>> [index for index, v in enumerate(l) if v == 'bar'] [1, 3] >>> [index for index, v in enumerate(l) if v == 'boink'] [] |
如果你没有发生,你可以检查布尔检查的结果,或只是做什么,如果你循环的结果:
1 2 3 | indexes = [index for index, v in enumerate(l) if v == 'boink'] for index in indexes: do_something(index) |
与熊猫更好地咀嚼数据
如果你有熊猫,你可以很容易地得到这个信息与一系列对象:
1 2 3 4 5 6 7 8 | >>> import pandas as pd >>> series = pd.Series(l) >>> series 0 foo 1 bar 2 baz 3 bar dtype: object |
比较检查将返回一系列布尔值:
1 2 3 4 5 6 | >>> series == 'bar' 0 False 1 True 2 False 3 True dtype: bool |
通过下标符号将布尔级数传递给级数,就得到了匹配的成员:
1 2 3 4 | >>> series[series == 'bar'] 1 bar 3 bar dtype: object |
如果只需要索引,index属性返回一系列整数:
1 2 | >>> series[series == 'bar'].index Int64Index([1, 3], dtype='int64') |
如果你想在列表或元组中使用它们,只需将它们传递给构造函数:
1 2 | >>> list(series[series == 'bar'].index) [1, 3] |
是的,你也可以使用列表理解和enumerate,但在我看来,这并不优雅——你在用Python做平等测试,而不是让用C编写的内置代码来处理它:
1 2 | >>> [i for i, value in enumerate(l) if value == 'bar'] [1, 3] |
这是XY问题吗?
The XY problem is asking about your attempted solution rather than your actual problem.
为什么需要列表中给定元素的索引?
如果您已经知道了值,为什么还要关心它在列表中的位置呢?
如果没有这个值,那么捕获
我通常会遍历列表,所以我通常会保留一个指向任何有趣信息的指针,使用enumerate获得索引。
如果您正在咀嚼数据,您可能应该使用panda——它拥有比我所展示的纯Python工作区更优雅的工具。
我不记得我自己需要什么。不过,我已经浏览了Python标准库,并看到了它的一些优秀用途。
它在
在Lib/mail .py中,它看起来像一个有序映射:
1 | key_list[key_list.index(old)] = new |
和
1 | del key_list[key_list.index(key)] |
在Lib / http / cookiejar。py,似乎是用来得到下个月的:
1 | mon = MONTHS_LOWER.index(mon.lower())+1 |
在Lib/tar文件.py类似于distutils,以获得一个切片到一个项目:
1 | members = members[:members.index(tarinfo)] |
在Lib / pickletools.py:
1 | numtopop = before.index(markobject) |
这些用法的共同之处在于,它们似乎对受限制的大小列表进行操作(这很重要,因为O(n)查找
虽然有它的用例,但它们相当少见。如果您发现自己正在寻找这个答案,请问问自己,您所做的是否最直接地使用了该语言为您的用例提供的工具。
所有带有
1 2 3 4 | 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),您可以存储第一个元素(n),当元素x等于您要查找的内容时,它是列表的索引。
1 2 3 4 5 | >>> alist = ['foo', 'spam', 'egg', 'foo'] >>> foo_indexes = [n for n,x in enumerate(alist) if x=='foo'] >>> foo_indexes [0, 3] >>> |
让我们的函数findindex
这个函数接受item和list作为参数,并返回list中item的位置,就像我们之前看到的那样。
1 2 3 4 5 | 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 | [1, 3, 5, 7] |
简单
1 2 3 | for n, i in enumerate([1, 2, 3, 4, 1]): if i == 1: print(n) |
输出:
1 2 | 0 4 |
你只要跟着就行了
1 2 3 4 | a = [['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']] b = ['phone', 'lost'] res = [[x[0] for x in a].index(y) for y in b] |
另一个选择
1 2 3 4 5 6 7 8 9 10 11 | >>> 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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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窗口时:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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开发,我对自己最初的答案感到有些尴尬,所以坦白地说,可以使用上面的代码;然而,获得相同行为的更习惯的方法是使用list comprehension和enumerate()函数。
是这样的:
1 2 3 4 5 6 7 8 9 | 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窗口时,会产生:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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在他之前的答案中所建议的。在我最初回答这个问题的时候,我甚至没有看到那个答案,因为我不理解它。我希望我稍微详细的例子将有助于理解。
如果上面的一行代码对您来说仍然没有意义,我强烈建议您理解谷歌"python列表",并花几分钟熟悉一下。它只是众多功能强大的特性之一,这些特性使使用Python开发代码成为一种乐趣。
来自FMc和user7177的答案的一个变体将给出一个dict,它可以返回任何条目的所有索引:
1 2 3 4 5 6 7 8 9 | >>> 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 2 3 4 5 6 7 8 | def find_element(p,t): i = 0 for e in p: if e == t: return i else: i +=1 return -1 |
由于Python列表是从零开始的,我们可以使用zip内置函数如下:
1 | >>> [i for i,j in zip(range(len(haystack)), haystack) if j == 'needle' ] |
其中"haystack"是有问题的列表,"needle"是要查找的条目。
(注意:这里我们使用i来迭代获得索引,但是如果我们需要更关注项目,我们可以切换到j。)
1 2 3 4 5 6 7 8 9 10 11 | 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
因此,你可以让它类似于JavaScript的
1 2 3 4 | try: index = array.index('search_keyword') except ValueError: index = -1 |
对此有一个更实用的答案。
1 | list(filter(lambda x: x[1]=="bar",enumerate(["foo","bar","baz","bar","baz","bar","a","b","c"]))) |
更一般的形式:
1 2 3 | def get_index_of(lst, element): return list(map(lambda x: x[0],\ (list(filter(lambda x: x[1]==element, enumerate(lst)))))) |
查找列表L中项目x的索引:
1 | idx = L.index(x) if (x in L) else -1 |
There is two possibility if the list has no repeated items that you need to check the index for
1 2 | eg: li=[10,20,30] # here need to get index of 20 means li.index(20) # will work properly because 20 is not repeated |
如果它的重复意味着它只会给出第一个索引
如果您需要获得项目所在的所有索引,这意味着
1 | eg: li=[10,20,30,20,40, 50, 10] # here need to get index of 20 means its have 2 index (1,3) |
要得到它,你需要像这样做
1 2 | li=[10,20,30,20,40, 50, 10] [i for i, e in enumerate(li) if e == 20] |
然后您将得到一个索引列表,如o/p [1,3]
让我们将名称
1 2 3 4 5 6 | import numpy as np lst = ["foo","bar","baz"] #lst: : 'list' data type print np.where( np.array(lst) == 'bar')[0][0] >>> 1 |
对于像我这样来自另一种语言的人来说,也许用一个简单的循环就能更容易理解和使用它:
1 2 3 4 5 | mylist = ["foo","bar","baz","bar"] newlist = enumerate(mylist) for index, item in newlist: if item =="bar": print(index, item) |
我很感激枚举到底做了什么?这帮助我理解。
如果性能值得关注:
在众多的答案中提到,
如果你确定你的清单上的项目不会重复,你可以很容易:
1 2 3 4 5 6 7 8 | myList = ["foo","bar","baz"] # Create the dictionary myDict = dict((e,i) for i,e in enumerate(myList)) # Lookup myDict["bar"] # Returns 1 # myDict.get("blah") if you don't want an error to be raised if element not found. |
如果你可能有重复的元素,并需要返回所有的索引:
1 2 3 4 5 6 7 8 9 10 | from collections import defaultdict as dd myList = ["foo","bar","bar","baz","foo"] # Create the dictionary myDict = dd(list) for i,e in enumerate(myList): myDict[e].append(i) # Lookup myDict["foo"] # Returns [0, 4] |
正如@TerryA所指出的,许多答案讨论了如何找到一个索引。
鉴于
1 2 3 4 | import more_itertools as mit iterable = ["foo","bar","baz","ham","foo","bar","baz"] |
代码
查找多个观测指标:
1 2 | list(mit.locate(iterable, lambda x: x =="bar")) # [1, 5] |
测试多个项目:
1 2 3 4 5 6 7 8 9 10 11 12 13 | list(mit.locate(iterable, lambda x: x in {"bar","ham <hr><p>使用dictionary,首先处理列表,然后将索引添加到其中</P>[cc lang="python"]from collections import defaultdict index_dict = defaultdict(list) word_list = ['foo','bar','baz','bar','any', 'foo', 'much'] for word_index in range(len(word_list)) : index_dict[word_list[word_index]].append(word_index) word_index_to_find = 'foo' print(index_dict[word_index_to_find]) # output : [0, 5] |