Ecco il modo Pythonic per farlo:
data = [['a','b'], ['a','c'], ['b','d']]
search = 'c'
any(e[1] == search for e in data)
Oppure ... beh, non ho intenzione di rivendicare questo è il "unico vero modo Pythonic" per farlo perché a un certo punto diventa un po 'soggettivo ciò che è Pythonic e ciò che non lo è, o quale metodo è più Pythonic di un altro. Ma usare lo stile any()
è decisamente più tipico di Python di un ciclo for
come ad es. RichieHindle's answer,
Ovviamente esiste un ciclo nascosto nell'implementazione di any
, sebbene si interrompa non appena trova una corrispondenza.
Poiché ero annoiato feci uno script di temporizzazione per confrontare le prestazioni delle diverse proposte, modificando alcuni come necessario per rendere l'API stesso.Ora, dovremmo tenere a mente che il più veloce non è sempre il migliore, e essere veloci non è sicuramente la stessa cosa di essere Pythonic. Detto questo, i risultati sono ... strani. A quanto pare i loop for
sono molto veloci, il che non è quello che mi aspettavo, quindi li prenderei con un pizzico di sale senza capire perché sono venuti fuori come loro.
Ad ogni modo, quando ho usato l'elenco definito nella questione con tre liste parziali di due elementi ciascuno, dal più veloce al più lento ottengo questi risultati:
- RichieHindle's answer con il ciclo
for
, un clock di 0,22 ms
- Terence Honles' first suggestion che crea un elenco, a 0,36 ms
- Pierre-Luc Bedard's answer (last code block), a 0,43 ms
- essenzialmente legati tra Markus's answer e
for
ciclo da the original question, a 0,48 ms
- Coady's answer usando
operator.itemgetter()
, a 0,53 ms
- Abbastanza vicino a contare come un legame tra Alex Martelli's answer con
ifilter()
e Anon's answer, a 0.67 ms (Alex è costantemente circa la metà di un microsecondo più veloce)
- Un altro vicino -Basta legame tra jojo's answer, miniera, Brandon E Taylor's (che è identico al mio), e Terence Honles' second suggestion utilizzando
any()
, tutti provenienti in alle 0.81-0.82 ms
- e poi user27221's answer utilizzando comprehensions elenco nidificati, a 0,95 ms
Ovviamente i tempi effettivi non sono significativi sull'hardware di nessun altro, ma le differenze tra di loro dovrebbero dare un'idea di quanto siano vicini i diversi metodi.
Quando uso una lista più lunga, le cose cambiano un po '. Ho iniziato con la lista nella domanda, con tre sottoliste, e ho aggiunto altre 197 sottoliste, per un totale di 200 sottoliste ciascuna di lunghezza due. Usando questa lista più, ecco i risultati:
- RichieHindle's answer, alle stesse 0,22 ms come con l'elenco più breve
- Coady's answer utilizzando
operator.itemgetter()
, di nuovo a 0,53 ms
- Terence Honles' first suggestion che crea un elenco, a 0.36 ms
- un altro legame virtuale tra Alex Martelli's answer con
ifilter()
e Anon's answer, a 0.67 ms
- nuovo una cravatta stretta-sufficiente tra la mia risposta, Brandon E Taylor's metodo identico, e Terence Honles' second suggestion utilizzando
any()
, tutti provenienti in alle 0.81-0.82 ms
Questi sono quelli che mantengono la loro temporizzazione originale quando l'elenco viene esteso. Il resto, che non lo fanno, sono
- Il
for
ciclo da the original question, a 1.24 ms
- Terence Honles' first suggestion che crea un elenco, a 7,49 ms
- Pierre-Luc Bedard's answer (last code block), alle 8 .12 ms
- Markus's answer, a 10.27 ms
- jojo's answer, a 19.87 ms
- E infine user27221's answer utilizzando list comprehension nidificate, a 60,59 ms
A questo punto della mia "carriera" in pitone, preferisco questo approccio poiché è molto facile da leggere. Potrei tornare a provare gli altri per le prestazioni, però. La mia lista diventa abbastanza grande ad un certo punto. C'è un posto dove posso confrontare le prestazioni dei diversi approcci? – greye
Usa il modulo 'timeit' per il test delle prestazioni di questo genere di cose: http://docs.python.org/library/timeit.html – RichieHindle
E se non sappiamo se il personaggio che stiamo cercando sia in la posizione [0] th, [1] st, [2] nd ecc. all'interno dell'elenco annidato? per esempio. stiamo cercando 'b', usando questo metodo restituirebbe solo ['a', 'b'] piuttosto che ['b', 'd']. –