Estoy tratando de llamar a una función para un rango de valores. Esa función devuelve una lista. El objetivo es combinar todas las listas devueltas en una lista.

Aquí hay una función de prueba que devuelve una lista:

def f(i):
    return [chr(ord('a') + i), chr(ord('b') + i), chr(ord('c') + i)]

Aquí hay una lista de comprensión que hace lo que necesito que se me ocurrió después de un poco de experimentación y mucha lectura de StackOverflow:

y = [a for x in (f(i) for i in range(5)) for a in x]

Sin embargo, no entiendo por qué y cómo funciona cuando un bucle simple que resuelve este problema se ve así:

y = []
for x in (f(i) for i in range(5)):
    for a in x:
        y.append(a)

Alguien puede explicar?

¡Gracias!

-1
KirEvse 1 oct. 2019 a las 22:06

3 respuestas

La mejor respuesta

Las comprensiones de listas anidadas son difíciles de leer. Pero si observa las dos expresiones, verá que contienen la misma lógica. En la comprensión de la lista, el primer a es la parte que desea mantener en la lista. Es igual a y.append(a) en el ciclo for. El for x in (f(i) for i in range(5)) es el mismo que en tu bucle for Lo mismo ocurre con la siguiente línea for a in x Entonces for x in (f(i) for i in range(5)) crea una lista x Entonces si tuviéramos la lista x ya podríamos escribir y= [a for a in x]

0
Bendik Knapstad 1 oct. 2019 a las 19:29

Respondiendo a esto:

Sin embargo, no entiendo por qué y cómo funciona (enumere las comprensiones) cuando un bucle simple que resuelve este problema se ve así (para bucles)

Sí, ambos pueden funcionar, pero hay algunas diferencias. Primero, con las comprensiones de listas, puede generar una lista (porque esa es la salida) después de asignarla a una variable. Mientras que en un bucle for, debe tener la lista creada (independientemente de si está vacía o no) si desea usar el método "append" más adelante para realizar cualquier operación de actualización / eliminación / reindexación.

En segundo lugar, simplicity . Si bien los for bucles pueden usarse en tareas complejas en las que necesita aplicar una amplia variedad de funciones, y tal vez usar RNG, las comprensiones de listas siempre son preferibles cuando se trata de lidiar con listas y realizar operaciones más bien "básicas" (de por supuesto, puedes comenzar a anidarlos y convertirlos en algo más complejo).

Tercero y finalmente, velocidad . Las comprensiones de listas tienden a realizar baster en comparación con bucles for para tareas simples.

Se puede leer más información detallada sobre listcomp y para bucles en el tutorial oficial de Python. https://docs.python.org/3/tutorial/datastructures.html

0
Celius Stingher 1 oct. 2019 a las 19:20

Esta puede ser una mejor ilustración, siguiendo la respuesta de Bendik Knapstad:

[
    a # element added to the list
    for x in (f(i) for i in range(5)) # outer loop
        for a in x # inner loop that assigns to element to be added to the list
]
0
KirEvse 1 oct. 2019 a las 19:47
58190864