Doble iteración en comprensión de listas [duplicado]

Resuelto ThomasH asked hace 15 años • 11 respuestas

En Python puedes tener múltiples iteradores en una lista por 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 del bucle anidado de las listas por comprensión de Python.

Mi pregunta es: ¿Puede un iterador de la comprensión referirse al otro? En otras palabras: ¿podría tener algo como esto?

[x for x in a for a in b]

¿Dónde 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 listas para lograr este resultado?

[1,2,3,4]

?? (Por favor, indique únicamente las respuestas de comprensión, ya que esto es lo que quiero saber).

ThomasH avatar Jul 29 '09 15:07 ThomasH
Aceptado

Suponga que tiene un texto lleno de oraciones y desea una variedad de palabras.

# Without list comprehension
list_of_words = []
for sentence in text:
    for word in sentence:
       list_of_words.append(word)
return list_of_words

Me gusta pensar en la comprensión de listas como extender el código horizontalmente.

Intenta dividirlo en:

# List Comprehension 
[word for sentence in text for word in sentence]

Ejemplo:

>>> text = (("Hi", "Steve!"), ("What's", "up?"))
>>> [word for sentence in text for word in sentence]
['Hi', 'Steve!', "What's", 'up?']

Esto también funciona para generadores.

>>> text = (("Hi", "Steve!"), ("What's", "up?"))
>>> gen = (word for sentence in text for word in sentence)
>>> for word in gen: print(word)
Hi
Steve!
What's
up?
Skam avatar Apr 20 '2016 05:04 Skam

Para responder a su pregunta con su propia sugerencia:

>>> [x for b in a for x in b] # Works fine

Si bien solicitó respuestas de comprensión de listas, permítame señalar también el excelente itertools.chain():

>>> from itertools import chain
>>> list(chain.from_iterable(a))
>>> list(chain(*a)) # If you're using python < 2.6
André Eriksson avatar Jul 29 '2009 08:07 André Eriksson

Vaya, supongo que encontré la respuesta: no me estaba preocupando lo suficiente qué bucle es interno y cuál es externo. La comprensión de la lista debería ser como:

[x for b in a for x in b]

para obtener el resultado deseado, y sí, un valor actual puede ser el iterador para el siguiente ciclo.

ThomasH avatar Jul 29 '2009 08:07 ThomasH