811 votos

Lista de filtrado: lista de comprensión vs lambda + filtro

Sucedió que me encontré tener un básico de filtrado de necesidad: tengo una lista y tengo que filtrar por un atributo de los elementos.

Mi código se vería así:

my_list = [i for i in my_list if i.attribute == value]

Pero luego pensé, ¿no sería mejor escribir algo como esto?

filter(lambda x: x.attribute == value, my_list)

Es más legible, y si es necesario para el rendimiento de la lambda se podrían tomar para ganar algo.

La pregunta es: ¿hay advertencias en el uso de la segunda forma? Cualquier diferencia de rendimiento? Me estoy perdiendo el Python el Camino™ completamente y debe hacerlo de otra manera (como el uso de itemgetter en lugar de la expresión lambda)?

558voto

Duncan Puntos 25356

Es extraño cómo tanta belleza varía para diferentes personas. Puedo encontrar la lista de comprensión mucho más clara que la fea filtro+lambda, pero el uso de lo que usted encuentra más fácil. Sin embargo, no deje de darle los nombres de variables que ya se utilizan para builtins, que es simplemente feo, y no abierto a la discusión.

Hay dos cosas que pueden ralentizar el uso de filtro.

La primera es la función de la sobrecarga de la llamada: tan pronto como se utiliza una función de Python (ya sea creado por def o lambda) es probable que el filtro será más lenta que la comprensión de listas. Es casi seguro que no es suficiente para la materia, y usted no debe pensar mucho sobre el rendimiento hasta que he cronometrado el código y nos pareció que para ser un cuello de botella, pero la diferencia va a estar allí.

Los otros gastos generales que se puedan aplicar es que la lambda está siendo forzado a acceder a un ámbito de la variable (value). Que es más lento que el acceso a una variable local y en Python 2.x la comprensión de lista sólo tiene acceso a las variables locales. Si usted está usando Python 3.x la comprensión de lista que se ejecuta en una función específica, por lo que también se accede value a través de un cierre y esta diferencia no se aplican.

La otra opción a considerar es el uso de un generador en lugar de una lista de comprensión:

def filterbyvalue(seq, value):
   for el in seq:
       if el.attribute==value: yield el

A continuación, en el código principal (que es donde la legibilidad realmente importante) que ha sustituido tanto la comprensión de listas y el filtro con una suerte significativo nombre de la función.

223voto

Tendayi Mawushe Puntos 10335

Esta es una especie de tema religioso en Python. Aunque Guido considera extracción map, filter y reduce de Python 3, no fue suficiente de un contragolpe que al final solo reduce fue trasladado desde construido-ins para functools.reduce.

Personalmente creo que la lista de comprensión más fácil de leer. Es más explícita de lo que está sucediendo a partir de la expresión [i for i in list if i.attribute == value] como todas las conductas que está en la superficie no dentro de la función de filtro.

Yo no me preocuparía demasiado por la diferencia de rendimiento entre los dos enfoques, como es marginal. Realmente sólo optimizar este si que resultó ser el cuello de botella en la aplicación cual es poco probable.

También desde el BDFL quería filter pasado desde el lenguaje, entonces seguramente que hace automáticamente la lista de comprensión más Python ;-)

28voto

Umang Puntos 2227

Aunque filter puede ser la "vía rápida", la "forma Pythonic" sería no preocuparse por esas cosas a menos que el rendimiento es absolutamente crítico (en cuyo caso no estar usando Python!).

8voto

unbeli Puntos 9573

Encuentro la segunda forma más legible. Te dice qué es exactamente la intención: filtrar la lista.
PD: No use 'lista' como un nombre de variable

6voto

gnibbler Puntos 103484

generalmente filter es un poco más rápido si se utiliza una función incorporada.

Espero la comprensión de la lista a ser ligeramente más rápido en su caso

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X