在Python中查找包含它的列表的索引

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

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

参考: 数据结构>更多关于列表

有一件事对于学习Python非常有用,那就是使用交互式帮助function:

 >>> help(["foo", "bar", "baz"]) Help on list object: class list(object) ... | | index(...) | L.index(value, [start, [stop]]) -> integer -- return first index of value | 

这往往会引导你到你正在寻找的方法。

大多数的答案解释了如何find一个单一的索引 ,但是他们的方法不会返回多个索引,如果该项目在列表中多次。 使用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()另一个小解决schemeitertools.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 

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

获取所有指标:

  indices = [i for i,x in enumerate(xs) if x == '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'] 

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

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

这里提出的所有function都重现了内在的语言行为,但是却掩盖了正在发生的事情。

 [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 

为什么编写一个具有exception处理function的函数,如果语言提供了你自己想做的方法呢?

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

这是清晰的,可读的解决scheme。

所有带有zipfunction的索引

 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') 

只要你可以去

 a = [['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']] b = ['phone', 'lost'] res = [[x[0] for x in a].index(y) for y in b] 

来自FMc和user7177的答案的变体将给出一个字典,可以返回任何条目的所有索引:

 >>> 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]} >>> 

你也可以用这个作为一个单一的class次来获得单个条目的所有索引。 虽然我没有使用set(a)来减lesslambda被调用的次数,但没有效率的保证。

另一种select

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

在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更好的数据传输

如果你有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的平等testing,而不是让C编写的内置代码处理它:

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

这是一个XY问题吗?

XY问题是询问您的尝试解决scheme,而不是您的实际问题。

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

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

如果这个值不在那里,那么捕获ValueError就相当冗长了 – 我宁愿避免这种情况。

我通常都在迭代列表,所以我通常会保留一个指向任何有趣的信息, 使用枚举来获取索引。

如果你正在使用数据,你可能应该使用pandas – 它比我所展示的纯Python解决方法要好得多。

我不记得需要list.index ,我自己。 但是,我已经浏览了Python标准库,并且看到了一些很好的用法。

idlelib有很多用途,用于GUI和文本parsing。

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)查找时间很重要),它们主要用于parsing(和UI闲)。

虽然有用例,但它们并不常见。 如果你发现自己在寻找这个答案,问问自己,你所做的是最直接的使用你的用例所提供的语言工具。

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

在获得索引之前确认该项目的存在。 这种方法的好处是函数总是返回一个索引列表 – 即使它是一个空列表。 它也适用于string。

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

这个解决scheme并不像其他的那么强大,但是如果你是初学者,只知道for循环,那么仍然有可能find一个item的第一个索引,同时避免ValueError:

 def find_element(p,t): i = 0 for e in p: if e == t: return i else: i +=1 return -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) 

如果string不在列表中,如果它不在列表中,那么location = -1

由于Python列表是基于零的,我们可以使用zip内build函数,如下所示:

 >>> [i for i,j in zip(range(len(haystack)),haystack) if j == 'needle' ] 

“haystack”是有问题的列表,“needle”是要查找的项目。

(注意:这里我们用i来迭代索引,但如果我们需要把焦点放在我们可以切换到j的项上)

获取列表中一个或多个(相同)项目的所有事件和位置

我们使用一个列表告诉我们'foo'的每个位置,而不是index()方法,因为这个告诉我们第一次出现'foo'而不是列表中的所有位置。 所以,如果我们有不止一次出现“foo”,我们可以使用这个列表理解来记住所有这些。 列表理解检查每个项目,将其与string“foo”进行比较,如果它是真实的,则将该位置存储在新列表foo_indexes中。 在循环结束时,列表将会保存所有的索引,以便在代码中使用。

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

执行search的function

我们可以做一个function,用于更多的场合。

 def searchItem(itm,lst): "Pass an item and a list and get all idexes of it in the list" indexes = [x for x in range(len(lst)) if lst[x]==itm] return indexes alist = ['foo','spam','egg','foo'] y = searchItem('foo',alist) >>> print(y) [0, 3]