Python Language Lista de Comprensiones con Bucles Anidados


Ejemplo

Las Comprensiones de lista pueden usar anidados for bucles. Puede codificar cualquier número de bucles for anidados dentro de una lista por comprensión, y cada uno for bucle puede tener una opción asociada if la prueba. Al hacerlo, el orden de la for las construcciones es del mismo orden que la hora de escribir una serie de anidado for declaraciones. La estructura general de las listas de comprensión se ve así:

[ expression for target1 in iterable1 [if condition1]
             for target2 in iterable2 [if condition2]...
             for targetN in iterableN [if conditionN] ]

Por ejemplo, el siguiente código aplanamiento una lista de listas utilizando múltiples for declaraciones:

data = [[1, 2], [3, 4], [5, 6]]
output = []
for each_list in data:
    for element in each_list:
        output.append(element)
print(output)
# Out: [1, 2, 3, 4, 5, 6]

se puede escribir de forma equivalente como una lista de comprensión con múltiples for construcciones:

data = [[1, 2], [3, 4], [5, 6]]
output = [element for each_list in data for element in each_list]
print(output)
# Out: [1, 2, 3, 4, 5, 6]

Demo en vivo

Tanto en la forma expandida como en la lista de comprensión, el bucle externo (primero para la declaración) aparece primero.


Además de ser más compacto, la comprensión anidada también es significativamente más rápida.

In [1]: data = [[1,2],[3,4],[5,6]]
In [2]: def f():
   ...:     output=[]
   ...:     for each_list in data:
   ...:         for element in each_list:
   ...:             output.append(element)
   ...:     return output
In [3]: timeit f()
1000000 loops, best of 3: 1.37 µs per loop
In [4]: timeit [inner for outer in data for inner in outer]
1000000 loops, best of 3: 632 ns per loop

La sobrecarga para la llamada de función anterior es de aproximadamente 140 ns .


En línea if s están anidados de manera similar, y puede ocurrir en cualquier posición después de la primera for :

data = [[1], [2, 3], [4, 5]]
output = [element for each_list in data
                if len(each_list) == 2
                for element in each_list
                if element != 5]
print(output)
# Out: [2, 3, 4]

Demo en vivo

Sin embargo, por razones de legibilidad, debe considerar el uso de bucles for tradicionales. Esto es especialmente cierto cuando el anidamiento tiene más de 2 niveles de profundidad y / o la lógica de la comprensión es demasiado compleja. la comprensión de múltiples listas de bucles anidadas podría ser propensa a errores o dar un resultado inesperado.