在元组或对象列表上使用Python的列表index()方法?

Python的列表types有一个index()方法,它接受一个参数并返回匹配参数的列表中的第一个项目的索引。 例如:

>>> some_list = ["apple", "pear", "banana", "grape"] >>> some_list.index("pear") 1 >>> some_list.index("grape") 3 

有没有一种优雅(惯用)的方式来扩展这个复杂的对象,如元组列表? 理想情况下,我希望能够做到这样的事情:

 >>> tuple_list = [("pineapple", 5), ("cherry", 7), ("kumquat", 3), ("plum", 11)] >>> some_list.getIndexOfTuple(1, 7) 1 >>> some_list.getIndexOfTuple(0, "kumquat") 2 

getIndexOfTuple()只是一个假设的方法,它接受一个子索引和一个值,然后返回该子索引给定值的列表项的索引。 我希望

有什么办法来实现这个一般性的结果,使用列表parsing或lambas或类似的“内联”? 我想我可以编写自己的类和方法,但如果Python已经有办法做到这一点,我不想重新发明轮子。

这个怎么样?

 >>> tuple_list = [("pineapple", 5), ("cherry", 7), ("kumquat", 3), ("plum", 11)] >>> [x for x, y in enumerate(tuple_list) if y[1] == 7] [1] >>> [x for x, y in enumerate(tuple_list) if y[0] == 'kumquat'] [2] 

正如在评论中指出的那样,这将得到所有的匹配。 要获得第一个,你可以这样做:

 >>> [y[0] for y in tuple_list].index('kumquat') 2 

对于所有解决scheme之间的速度差异,评论中有一个很好的讨论。 我可能会有点偏见,但我个人坚持一行,因为我们谈论的速度相对于为这个问题创build函数和导入模块相当微不足道,但是如果您打算将这个问题的数量做到非常大的元素,你可能想看看提供的其他答案,因为它们比我提供的更快。

这些列表parsing在一段时间后是凌乱的。

我喜欢这种Pythonic方法:

 from operator import itemgetter def collect(l, index): return map(itemgetter(index), l) # And now you can write this: collect(tuple_list,0).index("cherry") # = 1 collect(tuple_list,1).index("3") # = 2 

如果你需要你的代码都是超级高性能的:

 # Stops iterating through the list as soon as it finds the value def getIndexOfTuple(l, index, value): for pos,t in enumerate(l): if t[index] == value: return pos # Matches behavior of list.index raise ValueError("list.index(x): x not in list") getIndexOfTuple(tuple_list, 0, "cherry") # = 1 

一种可能性是使用operator模块的itemgetterfunction:

 import operator f = operator.itemgetter(0) print map(f, tuple_list).index("cherry") # yields 1 

itemgetter的调用返回一个函数,对于传递给它的任何东西,这个函数将等同于foo[0] 。 使用map ,然后将这个函数应用到每个元组,然后将这个信息提取到一个新的列表中,然后在那个列表上正常地调用index

 map(f, tuple_list) 

相当于:

 [f(tuple_list[0]), f(tuple_list[1]), ...etc] 

这又相当于:

 [tuple_list[0][0], tuple_list[1][0], tuple_list[2][0]] 

这使:

 ["pineapple", "cherry", ...etc] 

你可以用列表理解和索引()

 tuple_list = [("pineapple", 5), ("cherry", 7), ("kumquat", 3), ("plum", 11)] [x[0] for x in tuple_list].index("kumquat") 2 [x[1] for x in tuple_list].index(7) 1 

我会把它作为三联的评论,但由于缺乏评价,我还不能评论:

使用枚举器方法匹配元组列表中的子索引。 例如

 li = [(1,2,3,4), (11,22,33,44), (111,222,333,444), ('a','b','c','d'), ('aa','bb','cc','dd'), ('aaa','bbb','ccc','ddd')] # want pos of item having [22,44] in positions 1 and 3: def getIndexOfTupleWithIndices(li, indices, vals): # if index is a tuple of subindices to match against: for pos,k in enumerate(li): match = True for i in indices: if k[i] != vals[i]: match = False break; if (match): return pos # Matches behavior of list.index raise ValueError("list.index(x): x not in list") idx = [1,3] vals = [22,44] print getIndexOfTupleWithIndices(li,idx,vals) # = 1 idx = [0,1] vals = ['a','b'] print getIndexOfTupleWithIndices(li,idx,vals) # = 3 idx = [2,1] vals = ['cc','bb'] print getIndexOfTupleWithIndices(li,idx,vals) # = 4 

受这个问题的启发,我发现这很优雅:

 >>> tuple_list = [("pineapple", 5), ("cherry", 7), ("kumquat", 3), ("plum", 11)] >>> next(i for i, t in enumerate(tuple_list) if t[1] == 7) 1 >>> next(i for i, t in enumerate(tuple_list) if t[0] == "kumquat") 2 

好的,在vals(j)可能是一个错误,更正是:

 def getIndex(li,indices,vals): for pos,k in enumerate(lista): match = True for i in indices: if k[i] != vals[indices.index(i)]: match = False break if(match): return pos 
 tuple_list = [("pineapple", 5), ("cherry", 7), ("kumquat", 3), ("plum", 11)] def eachtuple(tupple, pos1, val): for e in tupple: if e == val: return True for e in tuple_list: if eachtuple(e, 1, 7) is True: print tuple_list.index(e) for e in tuple_list: if eachtuple(e, 0, "kumquat") is True: print tuple_list.index(e) 
 z = list(zip(*tuple_list)) z[1][z[0].index('persimon')] 

没有身体暗示lambdas?

Ÿ尝试这个工作。 我来这个postsearch答案。 我没有发现我喜欢,但是我感到一种感受:P

  l #[['rana', 1, 1], ['pato', 1, 1], ['perro', 1, 1]] map(lambda x:x[0], l).index("pato") #1 

编辑添加示例:

  l=[['rana', 1, 1], ['pato', 2, 1], ['perro', 1, 1], ['pato', 2, 2], ['pato', 2, 2]] 

通过条件提取所有项目:filter(lambda x:x [0] ==“pato”,l)#[['pato',2,1],['pato',2,2],['pato' 2,2]]

按索引提取所有项目:

  >>> filter(lambda x:x[1][0]=="pato", enumerate(l)) [(1, ['pato', 2, 1]), (3, ['pato', 2, 2]), (4, ['pato', 2, 2])] >>> map(lambda x:x[1],_) [['pato', 2, 1], ['pato', 2, 2], ['pato', 2, 2]] 

注意:_variables只能在交互式解释器中工作,正常的文本文件需要显式赋值,即_ = filter(lambda x:x [1] [0] ==“pato”,枚举(l))

Python的list.index(x)返回列表中第一个x的索引。 所以我们可以传递列表压缩返回的对象来获取它们的索引。

 >>> tuple_list = [("pineapple", 5), ("cherry", 7), ("kumquat", 3), ("plum", 11)] >>> [tuple_list.index(t) for t in tuple_list if t[1] == 7] [1] >>> [tuple_list.index(t) for t in tuple_list if t[0] == 'kumquat'] [2] 

在同一行中,如果有多个匹配元素,我们也可以得到索引列表。

 >>> tuple_list = [("pineapple", 5), ("cherry", 7), ("kumquat", 3), ("plum", 11), ("banana", 7)] >>> [tuple_list.index(t) for t in tuple_list if t[1] == 7] [1, 4]