Esta es la manera de hacerlo Pythonic:
data = [['a','b'], ['a','c'], ['b','d']]
search = 'c'
any(e[1] == search for e in data)
O ... bueno, no voy a reclamar este es el "único y verdadero camino Pythonic" de hacerlo porque en algún momento se hace un poco subjetivo, qué es Ptónico y qué no, o qué método es más Ptónico que otro. Pero el uso de any()
es definitivamente el estilo de Python más típico que un loop for
como en p. RichieHindle's answer,
Por supuesto, hay un bucle oculto en la implementación de any
, aunque se salga del bucle tan pronto como encuentre una coincidencia.
Como yo estaba aburrido Hice un script de tiempo para comparar el rendimiento de las diferentes sugerencias, modificando algunos de ellos si es necesario para hacer que el API de la misma.Ahora, debemos tener en cuenta que lo más rápido no siempre es lo mejor, y ser rápido definitivamente no es lo mismo que ser pitónico. Dicho esto, los resultados son ... extraños. Aparentemente los bucles for
son muy rápidos, que no es lo que esperaba, así que los tomaría con un grano de sal sin entender por qué salieron como lo hacen.
De todos modos, cuando utilicé la lista definida en la pregunta con tres sublistas de dos elementos cada uno, del más rápido al más lento consigo estos resultados:
- RichieHindle's answer con el bucle
for
, en la hora en 0,22 mu s
- Terence Honles' first suggestion que crea una lista, en 0.36 mu s
- Pierre-Luc Bedard's answer (last code block), en 0.43 mu s
- Esencialmente atada entre Markus's answer y la
for
bucle de the original question, a 0,48 mu s
- Coady's answer usando
operator.itemgetter()
, en 0.53 mu s
- suficientemente cerca para contar como un empate entre Alex Martelli's answer con
ifilter()
y Anon's answer, a 0.67 mu s (Alex es consistentemente alrededor de la mitad de un microsegundo más rápido)
- Otro estrecha lazo -suficiente entre jojo's answer, mina, Brandon E Taylor's (que es idéntica a la mía), y Terence Honles' second suggestion usando
any()
, todo llegando a 0.81-0.82 mu s
- y entonces user27221's answer usando listas por comprensión anidados, en 0,95 mu s
Obviamente, los tiempos reales no son significativos en el hardware de otra persona, pero las diferencias entre ellos deberían dar una idea de cuán cerca están los diferentes métodos.
Cuando uso una lista más larga, las cosas cambian un poco. Comencé con la lista en la pregunta, con tres sublistas, y añadí otras 197 sublistas, para un total de 200 sublistas de dos de longitud. Utilizando esta lista más larga, aquí están los resultados:
- RichieHindle's answer, en las mismas 0.22 mu s como con la lista más corta
- Coady's answer utilizando
operator.itemgetter()
, de nuevo en 0,53 mu s
- Terence Honles' first suggestion que crea una lista, a 0,36 microsiemens
- Otro empate virtual entre Alex Martelli's answer con
ifilter()
y Anon's answer, a 0.67 mu s
- nuevo un empate de cerca lo suficiente entre mi respuesta, Brandon E Taylor's método idéntico, y Terence Honles' second suggestion usando
any()
, todos llegando a 0.81-0.82 mu s
Esos son los que mantienen su calendario original cuando la lista se amplía. El resto, que no lo hacen, son
- El
for
bucle de the original question, en el 1,24 mu s
- Terence Honles' first suggestion que crea una lista, en 7.49 mu s
- Pierre-Luc Bedard's answer (last code block), en 8 .12 mu s
- Markus's answer, a 10.27 mu s
- jojo's answer, a 19,87 mu s
- Y finalmente user27221's answer usando listas por comprensión anidados, a 60,59 mu s
En este punto de mi "carrera" python estoy a favor de este enfoque, ya que es muy fácil de leer. Aunque tal vez regrese para probar los otros para el rendimiento. Mi lista se pone bastante grande en un punto. ¿Hay algún lugar donde pueda comparar el rendimiento de los diferentes enfoques? – greye
Utilice el módulo 'timeit' para las pruebas de rendimiento de este tipo de cosas: http://docs.python.org/library/timeit.html – RichieHindle
¿Qué pasa si no sabemos si el personaje que estamos buscando está en la posición [0] th, [1] st, [2] nd etc. dentro de la lista anidada? p.ej. estamos buscando 'b', con este método solo devolverá ['a', 'b'] en lugar de ['b', 'd']. –