Affectation de condition if sur une ligne

140

J'ai le code suivant

num1 = 10
someBoolValue = True

Je dois définir la valeur de num1à 20if someBoolValueis True; et ne rien faire autrement. Alors, voici mon code pour ça

num1 = 20 if someBoolValue else num1

Puis-je éviter la ...else num1pièce pour la rendre plus propre? Un équivalent à

if someBoolValue:
    num1 = 20

J'ai essayé de le remplacer par ...else passcomme ceci: num1=20 if someBoolValue else pass. Tout ce que j'ai eu, c'est une erreur de syntaxe. Je ne pouvais pas non plus simplement omettre la ...else num1partie.

bdhar
la source
2
Changez tout simplement en num1 = 20 if someBoolValue else 10. Ensuite, vous enregistrez également la num1=10ligne?
Thomas Ahle
Merci. Mais ce n'est pas exactement mon code. Je voulais dire que cela num1existe déjà ...
bdhar

Réponses:

196

Je ne pense pas que cela soit possible en Python, car ce que vous essayez de faire est probablement étendu à quelque chose comme ceci:

num1 = 20 if someBoolValue else num1

Si vous excluez else num1, vous recevrez une erreur de syntaxe car je suis tout à fait sûr que l'affectation doit en fait renvoyer quelque chose.

Comme d'autres l'ont déjà mentionné, vous pouvez le faire, mais c'est mauvais car vous finirez probablement par vous embrouiller lors de la lecture de ce morceau de code la prochaine fois:

if someBoolValue: num1=20

Je ne suis pas un grand fan du num1 = someBoolValue and 20 or num1pour exactement la même raison. Je dois en fait réfléchir à deux fois à ce que fait cette ligne.

La meilleure façon de réaliser réellement ce que vous voulez faire est la version originale:

if someBoolValue:
    num1 = 20

La raison pour laquelle c'est la meilleure version est parce que ce que vous voulez faire est très évident, et vous ne vous confondrez pas, ni avec quiconque d'autre va entrer en contact avec ce code plus tard.

En outre, en remarque, le num1 = 20 if someBoolValuecode Ruby est valide, car Ruby fonctionne un peu différemment.

Gel
la source
8
Selon PEP-308 ( docs.python.org/2.5/whatsnew/pep-308.html ), l'expression conditionnelle peut être rendue plus claire si elle est placée dans paren, comme dans num1 = (20 if someBoolValue else num1).
haridsv
46

Utilisez ceci:

num1 = 20 if someBoolValue else num1
Gigimon
la source
3
c'est ce que j'utilise .. et je cherche une alternative .. merci quand même !!
bdhar
Comment appeler ce bloc? Je veux dire quel est son nom?
fuat
1
c'est un opérateur ternaire
Chris Maes
Il ne faut pas utiliser cette approche si on parcourt de grands ensembles de données car elle introduit une affectation inutile au cas où nous finirions dans l'instruction else.
dapc
21

En une seule ligne:

if someBoolValue: num1 = 20

Mais ne fais pas ça. Ce style n'est normalement pas attendu. Les gens préfèrent le formulaire plus long pour plus de clarté et de cohérence.

if someBoolValue:
    num1 = 20

(De même, les casquettes de chameau doivent être évitées. Alors utilisez plutôt some_bool_value.)

Notez qu'une expression en ligne some_value if predicatesans elsepartie n'existe pas car il n'y aurait pas de valeur de retour si le prédicat était faux. Cependant, les expressions doivent avoir une valeur de retour clairement définie dans tous les cas. Ceci est différent de l'utilisation comme dans, par exemple, Ruby ou Perl.

Debilski
la source
2
Parce que cela devient difficile à lire et que vous finirez probablement par être confus par votre propre code, et ce n'est jamais une bonne idée.
Frost
@bdhar, pourquoi voulez-vous le mettre sur une seule ligne? Cela ne fonctionnera pas plus vite, ce sera juste plus difficile à lire pour les autres
John La Rooy
1
@gnibbler, aucune raison, en fait. je cherchais un formulaire plus court avec une meilleure lisibilité ..
bdhar
17

vous pouvez utiliser l'un des éléments suivants:

(falseVal, trueVal)[TEST]

TEST and trueVal or falseVal
Kerwal
la source
1
Affectation conditionnelle Nice one liner
minhas23
Comment s'appelle cette «structure»? Je n'ai jamais vu cela en ~ 6 mois d'apprentissage de Python.
Guimoute
1
Au moins ce ne sont pas des devoirs, à moins que vous n'en mettiez un devant eux, et deuxièmement, ils ne fonctionneront pas de la manière décrite ici. Le premier crée un tuple, puis sélectionne l'un de ses éléments par index. Cela ne fonctionnera que pour les tests qui retournent un entier entre -1 et 1, ou True/ False, car boolest une sous-classe de int. Dans tous les cas où le test renvoie quelque chose qui évaluerait simplement vrai, il échoue avec une exception. Le deuxième ne fonctionne que tant qu'il trueValn'évalue pas faux lui-même, ce qui entraînerait une falseValattribution même si le test était vrai.
Bachsau
il est joliment court, mais aussi très difficile à utiliser en toute sécurité comme "modèle recommandé", voir ci-dessus le commentaire de Bachsau ... (donc je l'ai décliné)
tverrbjelke
6

Non. Je suppose que vous espériez que quelque chose comme ça num1 = 20 if someBoolValuemarche, mais ce n'est pas le cas. Je pense que le meilleur moyen est d' ifutiliser la déclaration telle que vous l'avez écrite:

if someBoolValue:
    num1 = 20
Mark Byers
la source
5
num1 = 10 + 10*(someBoolValue is True)

C'est ma nouvelle réponse finale. La réponse précédente était la suivante et était exagérée pour le problème déclaré. Getting_too_clever == not Good. Voici la réponse précédente ... toujours bonne si vous voulez ajouter une chose pour Truecond et une autre pour False:

num1 = 10 + (0,10)[someBoolValue is True]

Vous avez mentionné num1avoir déjà une valeur qui devrait être laissée de côté. Je suppose num1 = 10que puisque c'est la première déclaration de l'article, l'opération à effectuer 20est donc d'ajouter 10.

num1 = 10
someBoolValue = True

num1 = 10 + (0,10)[someBoolValue is True]

print(f'num1 = {num1}\nsomeBoolValue = {someBoolValue}')

produit cette sortie

num1 = 20
someBoolValue = True
MikeyB
la source
Maintenant, je pense que j'aurais dû répondre 'num1 = 10 + 10 * (someBoolValue == True)' Problème défini comme la condition 'False' comme un no-op fondamentalement. S'il fallait choisir d'ajouter une valeur différente pour «Faux», alors la réponse précédente est un meilleur ajustement. Dois-je modifier mon message ou le faire dans les commentaires?
MikeyB
2
num1 = 20 * someBoolValue or num1
Kerwal
la source
2

Si vous souhaitez invoquer une méthode si un booléen est vrai, vous pouvez mettre else Nonefin au trinaire.

>>> a=1
>>> print(a) if a==1 else None
1
>>> print(a) if a==2 else None
>>> a=2
>>> print(a) if a==2 else None
2
>>> print(a) if a==1 else None
>>>
soultech67
la source
1

Si un code de ligne va certainement se produire pour vous, Python 3.8 introduit des expressions d'affectation affectueusement appelées «l'opérateur morse».

:=

someBoolValue and (num := 20)

Le 20sera attribué à numsi la première expression booléenne est True. L'affectation doit être entre parenthèses ici, sinon vous obtiendrez une erreur de syntaxe.

num = 10
someBoolValue = True

someBoolValue and (num := 20)
print(num) # 20

num = 10
someBoolValue = False

someBoolValue and (num := 20)
print(num) # 10
Vahid Hallaji
la source
0

Pour le futur voyageur temporel de Google, voici une nouvelle méthode (disponible à partir de python 3.8):

b = 1
if a := b:
    # this section is only reached if b is not 0 or false.
    # Also, a is set to b
    print(a, b)
Adnan Y
la source
-1

Vous pouvez certainement utiliser num1 = (20 if someBoolValue else num1) si vous le souhaitez.

Yaonan Qian
la source
Duplicata de la (des) réponse (s) ci-dessus?
Adam Smith
-1

Voici ce que je peux suggérer. Utilisez une autre variable pour dériver la clause if et l'affecter à num1.

Code:

num2 =20 if someBoolValue else num1
num1=num2
j raj
la source
-1

Autrement num1 = (20*boolVar)+(num1*(not boolVar))

Rody d'Argentine
la source
-1

Vous pouvez le faire de cette façon.

try:
    a = [i for i in [20] if False][0]
except IndexError:
    print("Do what ever you want here")

Vous pouvez résoudre votre problème de cette façon, mais l'utilisation de 'try / except block' n'est pas la meilleure pratique pour python.

Ayesh Weerasinghe
la source