compréhension de la liste python avec plusieurs 'if'

nous savons tous que python est

[f(x) for x in y if g(x)]

syntaxe.

Toutefois, l' AST la représentation de la compréhension de liste a de la place pour plus d'un "si", l'expression:

comprehension = (expr target, expr iter, expr* ifs)

quelqu'un peut-il me donner un exemple de code python qui produirait un AST avec plus d'une expression 'si'?

26
demandé sur Martijn Pieters 2013-03-06 17:11:58

5 réponses

empilez-les l'un après l'autre:

[i for i in range(100) if i > 10 if i < 50]

produit les nombres entiers entre 11 et 49 inclusivement.

34
répondu Emil Vikström 2013-03-06 13:13:35

La grammaire permet plusieurs instructions if parce que vous pouvez les mélanger entre les boucles for:

[j for i in range(100) if i > 10 for j in range(i) if j < 20]

les composantes de la compréhension doivent être considérées comme des énoncés imbriqués, ce qui se traduit par:

lst = []
for i in range(100):
    if i > 10:
        for j in range(i):
            if j < 20:
                lst.append(j)

Cela signifie également que vous pouvez utiliser plusieurs if déclarations sans for boucles entre:

[i for i in range(100) if i > 10 if i < 20]

bien que non sensuel (il suffit de combiner ceux qui utilisent and ou avec opérateurs enchaînés), il se traduit par un enchevêtrement légal ensemble d'états encore:

lst = []
for i in range(100):
    if i > 10:
        if i < 20:
            lst.append(i)

La grammaire et de l'analyseur de ne pas spécifiquement disallow un tel usage, de la même manière que Python ne vous interdit pas de nicher if consolidés.

Notez que PEP 202 -Lists Comprehensions (le document de proposition original qui a ajouté Cette caractéristique à la langue) comprend en fait une compréhension à deux conditions dans la section Exemples:

>>> print [(i, f) for i in nums for f in fruit if f[0] == "P" if i%2 == 1]
[(1, 'Peaches'), (1, 'Pears'), (3, 'Peaches'), (3, 'Pears')]
41
répondu Martijn Pieters 2018-09-07 17:16:36

en Utilisant le construit en all() vous permet de placer des expressions ou des fonctions booléennes multiples dans un itérable et de coller dans votre compréhension. Je pense que c'est un plutôt sous utilisé intégré dans et il garde la lisibilité élevée.

>>> [x for x in range(20) if all([1 < x < 10, not x & 1])]
[2, 4, 6, 8]

Ou

>>> [x for x in range(20) if all([foo(x), bar(x)])]

any() construit aussi fonctionnerait bien ici si seulement une condition devait être satisfaite:

>>> [x for x in range(20) if any([1 < x < 10, not x & 1])]
[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18]
6
répondu kylie.a 2015-09-21 17:52:30

langue de référence donne une meilleure idée à ce sujet:

list_comprehension  ::=  expression list_for
list_for            ::=  "for" target_list "in" old_expression_list [list_iter]
list_iter           ::=  list_for | list_if
list_if             ::=  "if" old_expression [list_iter]

Comme vous pouvez le voir la liste de compréhension est défini avec l'option list_iter à la fin-un seul list_iter. Maintenant, c' list_iter peut être un autre pour une partie de la compréhension de liste ou d'une condition. La condition if se termine à nouveau par un autrelist_iter. Ceci est essentiel pour permettre d'enchaîner plusieurs parties avec des conditions if optionnelles dans la même Liste. compréhension. Le fait que vous pourriez aussi construire un .. if X if Y if Z partie list_iter est juste un effet secondaire.

ainsi, bien que la possibilité d'enchaîner plusieurs conditions if-ne soit pas nécessaire, elle permet de définir toute la grammaire de cette façon.

5
répondu poke 2013-03-06 13:22:43

Essayez le code suivant:

>>> [i for i in range(50) if i in range(10,20)]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

qui donne un résultat inclusif.

-2
répondu Harsha B 2015-05-27 15:17:28