Python Language Liste des compréhensions avec des boucles imbriquées


Exemple

Liste compréhensions peuvent utiliser imbriqués for les boucles. Vous pouvez coder un nombre quelconque de boucles imbriquées pour l' intérieur d' une compréhension de la liste, et chaque for la boucle peut avoir une option associée if test. Ce faisant, l'ordre du for des constructions est le même ordre que lors de l' écriture d' une série d'imbriquée for les déclarations. La structure générale des compréhensions de listes ressemble à ceci:

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

Par exemple, le code suivant aplatit une liste de listes utilisant plusieurs for instructions:

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]

peut être écrit comme une compréhension équivalente de liste avec de multiples for les constructions:

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]

Démo en direct

À la fois dans la forme développée et dans la compréhension de la liste, la boucle externe (la première pour l'instruction) vient en premier.


En plus d'être plus compact, la compréhension imbriquée est également beaucoup plus rapide.

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 surcharge pour l'appel de fonction ci-dessus est d'environ 140ns .


En ligne if s sont imbriquées de la même manière, et peuvent se produire dans n'importe quelle position après le premier 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]

Démo en direct

Par souci de lisibilité, cependant, vous devriez envisager d'utiliser des boucles traditionnelles. Cela est particulièrement vrai lorsque l’imbrication a plus de 2 niveaux de profondeur et / ou que la logique de la compréhension est trop complexe. la compréhension multiple de la liste de boucles imbriquées pourrait être source d'erreurs ou donner des résultats inattendus.