Domanda

di Python tipo di lista ha un metodo index () che prende un parametro e restituisce l'indice del primo elemento nella lista corrispondente al parametro. Per esempio:

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

C'è un modo (idiomatica) aggraziato di estendere questo a liste di oggetti complessi, come tuple? Idealmente, mi piacerebbe essere in grado di fare qualcosa di simile:

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

getIndexOfTuple () è solo un metodo ipotetico che accetta un sottoindice e un valore, e quindi restituisce l'indice della voce di elenco con il valore dato a quel sottoindice. Spero

C'è qualche modo per raggiungere questo risultato generale, usando list comprehension o qualcosa Lambas o "in-line" del genere? Penso che potrei scrivere il mio di classe e metodo, ma io non voglio reinventare la ruota se Python ha già un modo per farlo.

È stato utile?

Soluzione

Che ne dici di questo?

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

Come sottolineato nei commenti, questo sarebbe ottenere tutte le partite. Per ottenere solo il primo, si può fare:

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

C'è una buona discussione nei commenti per quanto riguarda la differenza di velocità tra tutte le soluzioni distaccati. Posso essere un po 'prevenuto, ma io personalmente attenersi a una battuta, come la velocità di cui stiamo parlando è abbastanza insignificante contro la creazione di funzioni e l'importazione di moduli per questo problema, ma se si sta progettando di fare questo per una grande quantità di elementi che si potrebbe desiderare di guardare le altre risposte fornite, in quanto sono più veloce di quello che ho fornito.

Altri suggerimenti

Quei list comprehension sono disordinati dopo un po '.

Mi piace questo approccio 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

Se è necessario il codice di essere tutti super performante:

# 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 possibilità è quella di utilizzare la funzione itemgetter dal modulo operator :

import operator

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

La chiamata alla itemgetter restituisce una funzione che farà l'equivalente di foo[0] per qualsiasi cosa passata ad esso. Utilizzando map, quindi si applica quella funzione per ogni tupla, estraendo le informazioni in un nuovo elenco, sul quale quindi si chiama index come normale.

map(f, tuple_list)

è equivalente a:

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

che a sua volta è equivalente a:

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

che dà:

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

È possibile farlo con una comprensione lista e 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

porrei questo come un commento al Trittico, ma non posso commentare ancora a causa della mancanza di Valutazione:

Utilizzando il metodo enumeratore per abbinare il sottoindici in una lista di tuple. per es.

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

questa domanda , ho trovato questo molto 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, potrebbe essere un errore nel vals(j), la correzione è:

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

Nessun corpo suggerire lambda?

Y provare questo e lavora. Vengo a questa risposta messaggio di ricerca. Non scoperto che mi piace, ma mi sento un insingth: P

    l #[['rana', 1, 1], ['pato', 1, 1], ['perro', 1, 1]]

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

Modifica per aggiungere esempi:

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

estrarre tutti gli elementi di condizione:         Filtro (lambda x: x [0] == "pato", l) # [[ 'pato', 2, 1], [ 'pato', 2, 2], [ 'pato', 2, 2]]

estrarre tutti gli elementi di condizione con indice:

    >>> 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: _ variabile funziona solo in interprete interattivo file di testo normale y _ bisogno explicti assegnare, cioè _ = filtrata (lambda x: x [1] [0] == "pato", enumerare (l))

indice di una lista di Python (x) restituisce indice della prima occorrenza di x nella lista. Così possiamo passare gli oggetti restituiti dalla compressione lista per ottenere il loro indice.

>>> 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 stessa linea, si possono anche ottenere l'elenco dell'indice nel caso in cui non ci sono più elementi corrispondenti.

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

Credo che quanto segue non è il modo migliore per farlo (velocità ed eleganza preoccupazioni), ma bene, è potuto fare a:

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

lista di tuple con 2 membri può essere convertito in dict ordinato direttamente, strutture di dati sono in realtà la stessa, in modo che possiamo utilizzare il metodo dict al volo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top