web-dev-qa-db-fra.com

si d'autre dans une compréhension de liste

J'ai une liste l:

l = [22, 13, 45, 50, 98, 69, 43, 44, 1]

Pour les nombres supérieurs à 45 inclus, j'aimerais ajouter 1; et pour les nombres inférieurs, 5.

J'ai essayé

[x+1 for x in l if x >= 45 else x+5]

Mais cela me donne une erreur de syntaxe. Comment puis-je obtenir une if - else comme celle-ci dans une liste de compréhension?

372
user225312
>>> l = [22, 13, 45, 50, 98, 69, 43, 44, 1]
>>> [x+1 if x >= 45 else x+5 for x in l]
[27, 18, 46, 51, 99, 70, 48, 49, 6]

Faites quelque chose si <condition>, sinon faites autre chose.

420
user225312

La raison pour laquelle vous obtenez cette erreur est liée à la façon dont la compréhension de la liste est effectuée.

Gardez à l'esprit les points suivants:

[ expression for item in list if conditional ]

Est équivalent à:

for item in list:
    if conditional:
        expression

Où la expression est dans un format légèrement différent (pensez à changer le sujet et l'ordre des verbes dans une phrase).

Par conséquent, votre code [x+1 for x in l if x >= 45] fait ceci:

for x in l:
    if x >= 45:
        x+1

Cependant, ce code [x+1 if x >= 45 else x+5 for x in l] fait ceci (après avoir réorganisé la expression):

for x in l:
    if x>=45: x+1
    else: x+5
221
arboc7
[x+1 if x >= 45 else x+5 for x in l]

Et pour une récompense, voici le commentaire, j'ai écrit pour m'en souvenir la première fois que j'ai commis cette erreur:

L'expression conditionnelle de Python est a if C else b et ne peut pas être utilisée comme:

[a for i in items if C else b]

Le bon formulaire est:

[a if C else b for i in items]

Même s'il existe un formulaire valide:

[a for i in items if C]

Mais ce n’est pas la même chose, c’est comment vous filtrez par C, mais ils peuvent être combinés:

[a if tC else b for i in items if fC]
189
Dan D.

Vous devez mettre l'expression au début de la liste compréhension, une instruction if à la fin des filtres!

[x+1 if x >= 45 else x+5 for x in l]
96
AndiDog

Comme dans [a if condition1 else b for i in list1 if condition2], les deux ifs avec condition1 et condition2 font deux choses différentes. La partie (a if condition1 else b) provient d'une expression lambda:

lambda x: a if condition1 else b

tandis que l'autre condition2 est un autre lambda:

lambda x: condition2

La compréhension de la liste complète peut être considérée comme une combinaison de map et filter:

map(lambda x: a if condition1 else b, filter(lambda x: condition2, list1))
17
Xiaojun Chen

Vous pouvez également mettre l'expression conditionnelle entre parenthèses dans la liste de compréhension:

    l = [22, 13, 45, 50, 98, 69, 43, 44, 1]
    print [[x+5,x+1][x >= 45] for x in l]

[false, true] [condition] est la syntaxe

16
Stefan Gruenwald

Je viens d'avoir un problème similaire, et a trouvé cette question et les réponses vraiment utiles. Voici la partie à propos de laquelle j'ai été confus. Je l'écris explicitement parce que personne ne l'a dit simplement en anglais:

L'itération va à la fin.

Normalement, une boucle va

for this many times:
    if conditional: 
        do this thing
    else:
        do something else  

Tout le monde dit la partie compréhension de la liste comme le faisait la première réponse,

[ expression for item in list if conditional ] 

mais ce n'est pas ce que vous faites dans ce cas. (J'essayais de le faire de cette façon)

Dans ce cas, c'est plus comme ça:

[ expression if conditional else other thing for this many times ] 
9
szeitlin

Vous pouvez déplacer le conditionnel vers:

v = [22, 13, 45, 50, 98, 69, 43, 44, 1]
[ (x+1 if x >=45 else x+5)  for x in v ]

Mais cela commence à avoir l'air un peu moche, alors vous feriez mieux d'utiliser une boucle normale. Notez que j’ai utilisé v au lieu de l pour réduire la confusion avec le nombre 1 (je pense que l et O devraient être évités comme noms de variables, quelles que soient les circonstances). , même dans le code exemple rapide et sale).

6
Jeet