在元组或对象列表上使用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]