¿Utilizando el método index () de la lista de Python en una lista de tuplas u objetos?

El tipo de lista de Python tiene un método index () que toma un parámetro y devuelve el índice del primer elemento de la lista que coincide con el parámetro. Por ejemplo:

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

¿Existe una forma elegante (idiomática) de extender esto a las listas de objetos complejos, como las tuplas? Idealmente, me gustaría poder hacer algo como esto:

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

getIndexOfTuple () es solo un método hipotético que acepta un subíndice y un valor, y luego devuelve el índice del elemento de la lista con el valor dado en ese subíndice. espero

¿Hay alguna manera de lograr ese resultado general, usando listas de comprensión o lambas o algo “en línea” como ese? Creo que podría escribir mi propia clase y método, pero no quiero reinventar la rueda si Python ya tiene una manera de hacerlo.

¿Qué tal esto?

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

Como se señala en los comentarios, esto obtendría todas las coincidencias. Para obtener el primero, puedes hacer:

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

Hay una buena discusión en los comentarios sobre la diferencia de velocidad entre todas las soluciones publicadas. Puede que esté un poco sesgado, pero personalmente me atendría a una sola línea, ya que la velocidad de la que estamos hablando es bastante insignificante en comparación con la creación de funciones y la importación de módulos para este problema, pero si planea hacerlo con una cantidad muy grande de los elementos que podría querer ver en las otras respuestas proporcionadas, ya que son más rápidas de lo que yo proporcioné.

Esas comprensiones de la lista son desordenadas después de un tiempo.

Me gusta este enfoque pythonico:

 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 

Si necesita que su código sea todo super rendimiento:

 # 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 

Una posibilidad es usar la función itemgetter del módulo operator :

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

La llamada a itemgetter devuelve una función que hará el equivalente de foo[0] para cualquier cosa que se le pase. Usando el map , luego aplica esa función a cada tupla, extrayendo la información en una nueva lista, en la que luego llama al index como de costumbre.

 map(f, tuple_list) 

es equivalente a:

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

que a su vez es equivalente a:

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

lo que da:

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

Puedes hacer esto con una lista de comprensión e índice ()

 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 

Pondría esto como un comentario para Tríptico, pero no puedo comentar aún debido a la falta de calificación:

Usar el método del enumerador para hacer coincidir los subíndices en una lista de tuplas. p.ej

 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 

Inspirado por esta pregunta , me pareció bastante elegante:

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

ok, podría ser un error en vals(j) , la corrección es:

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

¿Ningún cuerpo sugiere lambdas?

Intenta esto y funciona. Vengo a este post buscando respuesta. No encontré lo que me gusta, pero siento un insincto: P

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

Editar para agregar ejemplos:

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

extraiga todos los elementos por condición: filtro (lambda x: x [0] == “pato”, l) # [[‘pato’, 2, 1], [‘pato’, 2, 2], [‘pato’, 2, 2]]

extraer todos los artículos por condición con índice:

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

Nota: la variable _ solo funciona en el intérprete interactivo y el archivo de texto normal _ necesita una asignación explícita, es decir, _ = filtro (lambda x: x [1] [0] == “pato”, enumerar (l))

List.index (x) de Python devuelve el índice de la primera aparición de x en la lista. Así podemos pasar los objetos devueltos por compresión de lista para obtener su índice.

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

Con la misma línea, también podemos obtener la lista de índices en caso de que haya varios elementos coincidentes.

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

Supongo que la siguiente no es la mejor manera de hacerlo (problemas de velocidad y elegancia) pero, bueno, podría ayudar:

 from collections import OrderedDict as od t = [('pineapple', 5), ('cherry', 7), ('kumquat', 3), ('plum', 11)] list(od(t).keys()).index('kumquat') 2 list(od(t).values()).index(7) 7 # bonus : od(t)['kumquat'] 3 

La lista de tuplas con 2 miembros se puede convertir a dictados ordenados directamente, las estructuras de datos son en realidad las mismas, por lo que podemos usar el método dict sobre la marcha.