255 votes

Compréhension de listes en une ligne : variantes if-else

Il s'agit plutôt de la syntaxe de compréhension des listes en python. J'ai une compréhension de liste qui produit une liste de nombres impairs dans un intervalle donné :

[x for x in range(1, 10) if x % 2]

Cela fait un filtre - j'ai une liste de sources, où j'enlève les numéros pairs ( if x % 2 ). J'aimerais utiliser quelque chose comme if-then-else ici. Le code suivant échoue :

>>> [x for x in range(1, 10) if x % 2 else x * 100]
  File "<stdin>", line 1
    [x for x in range(1, 10) if x % 2 else x * 100]
                                         ^
SyntaxError: invalid syntax

Il existe une expression python comme if-else :

1 if 0 is 0 else 3

Comment l'utiliser à l'intérieur d'une liste de compréhension ?

1 votes

Pour ce que ça vaut, vous avez une "compréhension de liste", pas un générateur. La syntaxe ultime est la même, sauf que les générateurs utilisent la fonction () au lieu de [] .

0 votes

2 votes

Il m'a fallu un moment pour comprendre pourquoi if x % 2 élimine les nombres pairs (au lieu de les conserver) - c'est parce que lorsque les x est même le x % 2 entraîne 0 qui, à son tour, est évalué à False alors que tout int sauf 0 évalue à True .

477voto

shx2 Points 14025

x if y else z est la syntaxe de l'expression que vous retournez pour chaque élément. Ainsi, vous avez besoin de :

[ x if x%2 else x*100 for x in range(1, 10) ]

La confusion vient du fait que vous utilisez une filtre dans le premier exemple, mais pas dans le second. Dans le second exemple, vous êtes seulement cartographie chaque valeur à une autre, en utilisant une expression à opérateur ternaire.

Avec un filtre, vous avez besoin :

[ EXP for x in seq if COND ]

Sans filtre, vous avez besoin :

[ EXP for x in seq ]

et dans votre deuxième exemple, l'expression est "complexe", et il se trouve qu'elle fait intervenir un if-else .

2 votes

J'ai une question... [x for x in range(1, 10) if x % 2] est une syntaxe correcte. [x if x % 2 for x in range(1, 10)] - ce n'est pas le cas, mais [x if x%2 else x*100 for x in range(1, 10)] est encore une fois, une syntaxe correcte. Comment cela se fait-il ?

0 votes

@tkoomzaaskz dans votre deuxième exemple, il ne s'agit ni d'un opérateur ternaire-if-else (il manque l'élément else ), ni un filtre (puisqu'il se trouve sur le site de l EXP partie de la compréhension de la liste)

3 votes

@tkoomzaaskz Pour plus de clarté, notez que vous pouvez ajouter une deuxième if à la fin : [x if x%2 else x*100 for x in range(1, 10) if not x%3] Le premier if fait partie de l'opérateur ternaire, le second if fait partie de la syntaxe de compréhension des listes. L'ensemble x if x%2 else x*100 est "au même niveau" qu'un simple 2*x c'est l'expression à évaluer sur le côté gauche de la fonction for lorsque le filtrage de if not x%3 a déjà eu lieu.

31voto

georgesl Points 4116
[x if x % 2 else x * 100 for x in range(1, 10) ]

20voto

Stefan Gruenwald Points 494

Vous pouvez aussi le faire avec la compréhension des listes :

A=[[x*100, x][x % 2 != 0] for x in range(1,11)]
print A

1 votes

Très bien. Une tranche booléenne. Merci, vous venez de me donner une solution plus facile à lire.

2 votes

Vous pouvez également procéder à une double affectation comme suit : A,B = [10,11][a==19], [1,14][a==20]

15voto

sjcipher Points 2626

Juste une autre solution, en espérant que quelqu'un l'apprécie :

Utilisation : [Faux, Vrai] [Expression]

>>> map(lambda x: [x*100, x][x % 2 != 0], range(1,10))
[1, 200, 3, 400, 5, 600, 7, 800, 9]
>>>

4voto

Mido Points 21

Comment mettre au carré une liste d'un tableau de valeurs négatives et positives ?

my_list=[-2,-3,0,1,5]
squred_values=[]

squred_values=[-i**2 if i<0 else i**2 for i in my_list]

ou

for i in my_list:
    if i<0:
        squred_values.append( -i**2)`enter code here`
    else:
        squred_values.append( i**2)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X