En Python puedes tener múltiples iteradores en una lista de comprensión, como
[(x,y) for x in a for y in b]
para algunas secuencias adecuadas a y b. Soy consciente de la semántica de bucle anidado de las comprensiones de listas de Python.
Mi pregunta es: ¿puede un iterador en la comprensión referirse al otro? En otras palabras: ¿podría tener algo como esto?
[x for x in a for a in b]
donde el valor actual del bucle externo es el iterador del interno?
Como ejemplo, si tengo una lista anidada:
a=[[1,2],[3,4]]
¿Cuál sería la expresión de comprensión de la lista para lograr este resultado?
[1,2,3,4]
?? (Por favor, solo enumere las respuestas de comprensión, ya que esto es lo que quiero averiguar).
fuente
[x for b in a for x in b]
Esto siempre ha sido molesto sobre python. Esta sintaxis es muy al revés. La forma general dex for x in y
siempre tiene la variable directamente después de for, alimenta la expresión a la izquierda de for. Tan pronto como haces una doble comprensión, tu variable iterada más recientemente está repentinamente tan "lejos". Es incómodo y no se lee de forma natural en absoluto¡Espero que esto ayude a alguien más ya
a,b,x,y
que no tiene mucho significado para mí! Supongamos que tiene un texto lleno de oraciones y desea una serie de palabras.Me gusta pensar en la comprensión de la lista como un código de estiramiento horizontal.
Intenta dividirlo en:
Ejemplo:
Esto también funciona para generadores
fuente
Caramba, creo que encontré la respuesta: no me estaba preocupando lo suficiente sobre qué bucle es interno y cuál es externo. La comprensión de la lista debería ser como:
para obtener el resultado deseado, y sí, un valor actual puede ser el iterador para el siguiente ciclo.
fuente
El orden de los iteradores puede parecer contrario a la intuición.
Toma por ejemplo:
[str(x) for i in range(3) for x in foo(i)]
Vamos a descomponerlo:
fuente
[(output in loop 2) (loop 1) (loop 2)]
con(loop 1) = for i in range(3)
y(loop 2) = for x in foo(i):
y(output in loop 2) = str(x)
.ThomasH ya ha agregado una buena respuesta, pero quiero mostrar lo que sucede:
Supongo que Python analiza la comprensión de la lista de izquierda a derecha. Esto significa que el primer
for
bucle que ocurra se ejecutará primero.El segundo "problema" de esto es que
b
se "filtra" de la comprensión de la lista. Después de la primera lista exitosa comprensiónb == [3, 4]
.fuente
x = 'hello';
[x for x in xrange(1,5)];
print x # x is now 4
Si desea mantener la matriz multidimensional, debe anidar los corchetes de la matriz. vea el ejemplo a continuación donde se agrega uno a cada elemento.
fuente
Esta técnica de memoria me ayuda mucho:
[ <RETURNED_VALUE> <OUTER_LOOP1> <INNER_LOOP2> <INNER_LOOP3> ... <OPTIONAL_IF> ]
Y ahora puedes pensar en R eturn + O uter -loop como el único R ight O rden
Sabiendo lo anterior, el orden en la lista completa incluso para 3 bucles parece fácil:
porque lo anterior es solo un:
para iterar una lista / estructura anidada, la técnica es la misma: por
a
la pregunta:uno para el otro nivel anidado
y así
fuente
Siento que esto es más fácil de entender.
fuente
Además, puede usar la misma variable para el miembro de la lista de entrada a la que se accede actualmente y para el elemento dentro de este miembro. Sin embargo, esto incluso podría hacerlo más (lista) incomprensible.
Primero
for x in input
se evalúa, lo que lleva a una lista de miembros de la entrada, luego, Python recorre la segunda partefor x in x
durante la cual el valor actual es sobrescrito por el elemento actual al que está accediendo, luego el primerox
define lo que queremos devolver.fuente
Esta función flatten_nlevel llama recursivamente a la lista1 anidada para que se convierta en un nivel. Probar esto
salida:
fuente
flatten_nlevel(sublist, flat_list)
, ¿verdad?