Piense en una función a la que estoy llamando por sus efectos secundarios, no por devolver valores (como imprimir en pantalla, actualizar GUI, imprimir en un archivo, etc.).
def fun_with_side_effects(x):
...side effects...
return y
Ahora, ¿es Pythonic usar listas por comprensión para llamar a esta función?
[fun_with_side_effects(x) for x in y if (...conditions...)]
Tenga en cuenta que no guardo la lista en ningún lado
O debería llamar a esta función así:
for x in y:
if (...conditions...):
fun_with_side_effects(x)
¿Cuál es mejor y por qué?
python
list-comprehension
sinan
fuente
fuente
for ... in
se usa en ambos casos, ¡lo que lleva a preguntas como esta!Respuestas:
Es muy anti-Pythonic hacerlo, y cualquier Pythonista experimentado te dará un infierno. La lista intermedia se desecha una vez creada y, potencialmente, podría ser muy, muy grande y, por lo tanto, costosa de crear.
fuente
for
antes, para deshacerme delif
).No debe utilizar una lista de comprensión porque, como ha dicho la gente, creará una gran lista temporal que no necesita. Los dos métodos siguientes son equivalentes:
con la definición de
consume
de laitertools
página de manual:Por supuesto, este último es más claro y más fácil de entender.
fuente
map
puede que no sea tan intuitivo si no ha realizado programación funcional antes.consume = collections.deque(maxlen=0).extend
Las listas por comprensión son para crear listas. Y a menos que en realidad está creando una lista, usted debe no utilizar listas por comprensión.
Entonces obtuve la segunda opción, simplemente iterando sobre la lista y luego llamar a la función cuando se apliquen las condiciones.
fuente
Segundo es mejor.
Piense en la persona que necesitaría comprender su código. Puedes conseguir mal karma fácilmente con el primero :)
Puede ir al medio entre los dos usando filter (). Considere el ejemplo:
fuente
lambda x : x > 3
.for el in (x for x in y if x > 3):
.el
yx
puede tener el mismo nombre, pero eso podría confundir a la gente.Depende de tu objetivo.
Si está intentando realizar alguna operación en cada objeto de una lista, debe adoptar el segundo enfoque.
Si está intentando generar una lista a partir de otra lista, puede utilizar la comprensión de listas.
fuente
Tu puedes hacer
pero no es muy bonito.
fuente
Usar una lista de comprensión para sus efectos secundarios es feo, no pitónico, ineficiente y yo no lo haría. En su
for
lugar, usaría un bucle, porque unfor
bucle indica un estilo de procedimiento en el que los efectos secundarios son importantes.Pero, si insiste absolutamente en usar una comprensión de lista para sus efectos secundarios, debe evitar la ineficiencia usando una expresión generadora. Si insiste absolutamente en este estilo, haga uno de estos dos:
o:
Estas son expresiones generadoras y no generan una lista aleatoria que se descarta. Creo que el
all
formulario es quizás un poco más claro, aunque creo que ambos son confusos y no deberían usarse.Creo que esto es feo y en realidad no lo haría en código. Pero si insistes en implementar tus bucles de esta manera, así es como lo haría yo.
Tiendo a sentir que las listas por comprensión y las similares deberían indicar un intento de usar algo que al menos se parezca ligeramente a un estilo funcional. Poner cosas con efectos secundarios que rompan esa suposición hará que las personas tengan que leer su código con más cuidado, y creo que eso es algo malo.
fuente
fun_with_side_effects
devuelve True?itertools.consume
ya no existe, probablemente porque usar comprensiones con efectos secundarios es feo.