Using index () method of Python list in list of tuples or objects?

The Python list type has an index () method that takes one parameter and returns the index of the first item in the list corresponding to the parameter. For example:

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

Is there an elegant (idiomatic) way to extend it to lists of complex objects, such as tuples? Ideally, I would like to do something like this:

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

getIndexOfTuple () is just a hypothetical method that takes a subindex and value, and then returns the index of the list item with the given value in that subindex. I hope that

Is there any way to achieve this overall result using lists or lambas or something like "in-line"? I think I could write my own class and method, but I don't want to reinvent the wheel if Python already has a way to do this.

+42
python list tuples reverse-lookup
Jun 03 '09 at 20:01
source share
11 answers

How about this?

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

As stated in the comments, this will result in all matches being received. To get the first, you can:

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

There is a good discussion in the comments regarding the speed difference between all posted solutions. I may be a little biased, but I personally will stick to the single-line interface, because the speed we are talking about is pretty slow compared to creating functions and importing modules for this problem, but if you plan to do this in a very large amount of elements that you you might want to look at the other answers provided as they are faster than I provided.

+57
Jun 03 '09 at 20:07
source share

These message lists are messy after a while.

I like this Pythonic approach:

 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 

If you need your code to be super efficient:

 # 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 
+26
Jun 03 '09 at 20:54
source share

One possibility is to use the itemgetter function from the operator module:

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

The call to itemgetter returns a function that will execute the equivalent of foo[0] for all passed to it. Using map , you then apply this function to each tuple, extracting the information into a new list, after which you call index as usual.

 map(f, tuple_list) 

equivalent to:

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

which in turn is equivalent to:

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

which gives:

 ["pineapple", "cherry", ...etc] 
+9
Jun 03 '09 at 20:12
source share

You can do it with list and index ()

 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 
+5
Jun 03 '09 at 20:50
source share

I would post this as a comment on Triptych, but I can not comment yet because of the lack of rating:

Using the enumeration method to match by sub-indices in a list of tuples. eg.

 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 
+2
Jul 27. 2018-11-21T00:
source share

Inspired by this question , I found it pretty elegant:

 >>> 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 
+2
Feb 17 '16 at 1:49
source share

ok, this may be a bug in vals vals(j) , amendment:

 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 
+1
Jun 19 '12 at 17:38
source share
 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) 
+1
Oct. 16
source share
 z = list(zip(*tuple_list)) z[1][z[0].index('persimon')] 
0
Jan 16 '13 at 17:19
source share

No body offers lambda?

Try it and work. I come to the answer to this post. I did not find what I like, but I feel depressed: P

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

Edit to add examples:

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

extract all elements by condition: filter (lambda x: x [0] == "pato", l) # [['pato', 2, 1], ['pato', 2, 2], ['pato', 2, 2]]

extract all elements by condition with index:

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

Note: the variable _ only works in the interactive interpreter y normal text file _ requires explicti assign, ie _ = filter (lambda x: x [1] [0] == "pato", enumerate (l))

0
May 4 '16 at 8:21
source share

Python list.index (x) returns the index of the first occurrence of x in the list. Thus, we can pass objects returned by list compression to get their index.

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

With the same line, we can also get a list of indices in case there are several matched elements.

 >>> 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] 
0
Jun 09 '17 at 1:54 on
source share



All Articles