Est-ce que Python a un opérateur ternaire conditionnel?


Answers

Vous pouvez indexer dans un tuple:

(falseValue, trueValue)[test]

test doit renvoyer True ou False .
Il pourrait être plus sûr de toujours l'implémenter comme:

(falseValue, trueValue)[test == True]

ou vous pouvez utiliser le Boolean intégré bool() pour assurer une valeur Boolean :

(falseValue, trueValue)[bool(<expression>)]
Question

Si Python n'a pas d'opérateur conditionnel ternaire, est-il possible de simuler un opérateur utilisant d'autres constructions de langage?




Vous pourriez souvent trouver

cond and on_true or on_false

mais cela conduit à un problème lorsque on_true == 0

>>> x = 0
>>> print x == 0 and 0 or 1 
1
>>> x = 1
>>> print x == 0 and 0 or 1 
1

où vous attendez pour un opérateur ternaire normal ce résultat

>>> x = 0
>>> print 0 if x == 0 else 1 
0
>>> x = 1
>>> print 0 if x == 0 else 1 
1



Est-ce que Python a un opérateur ternaire conditionnel?

Oui. Du fichier de grammaire :

test: or_test ['if' or_test 'else' test] | lambdef

La partie d'intérêt est:

or_test ['if' or_test 'else' test]

Ainsi, une opération conditionnelle ternaire est de la forme:

expression1 if expression2 else expression3

expression3 sera évaluée paresseusement (c'est-à-dire, évaluée seulement si expression2 est fausse dans un contexte booléen). Et à cause de la définition récursive, vous pouvez les enchaîner indéfiniment (bien que cela puisse être considéré comme un mauvais style).

expression1 if expression2 else expression3 if expression4 else expression5 # and so on

Une note sur l'utilisation:

Notez que chaque if doit être suivi avec un else . Les personnes qui apprennent la compréhension des listes et les expressions génératrices peuvent trouver que c'est une leçon difficile à apprendre - ce qui suit ne fonctionnera pas, car Python attend une troisième expression pour un autre:

[expression1 if expression2 for element in iterable]
#                          ^-- need an else here

ce qui soulève une SyntaxError: invalid syntax . Donc, ce qui précède est soit une partie incomplète de la logique (peut-être l'utilisateur s'attend à un non-op dans la fausse condition) ou ce qui peut être destiné à utiliser expression2 comme un filtre - note que ce qui suit est légal Python:

[expression1 for element in iterable if expression2]

expression2 fonctionne comme un filtre pour la compréhension de la liste et n'est pas un opérateur conditionnel ternaire.

Syntaxe alternative pour un cas plus étroit:

Vous pourriez trouver quelque peu douloureux d'écrire ce qui suit:

expression1 if expression1 else expression2

expression1 devra être évaluée deux fois avec l'utilisation ci-dessus. Il peut limiter la redondance s'il s'agit simplement d'une variable locale. Cependant, un idiome Pythonic commun et performant pour ce cas d'utilisation est d'utiliser le comportement de raccourci:

expression1 or expression2

ce qui est équivalent en sémantique. Notez que certains guides de style peuvent limiter cette utilisation pour des raisons de clarté - cela ajoute beaucoup de sens à très peu de syntaxe.




Oui.

>>> b = (True if 5 > 4 else False)
>>> print b
True



Un opérateur pour une expression conditionnelle en Python a été ajouté en 2006 dans le cadre de Python Enhancement Proposal 308 . Sa forme diffère de commune ?: Opérateur et c'est:

<expression1> if <condition> else <expression2>

ce qui équivaut à:

if <condition>: <expression1> else: <expression2>

Voici un exemple:

result = x if a > b else y

Une autre syntaxe qui peut être utilisée (compatible avec les versions antérieures à 2.5):

result = (lambda:y, lambda:x)[a > b]()

où les opérandes sont évalués paresseusement .

Une autre méthode consiste à indexer un tuple (ce qui n'est pas cohérent avec l'opérateur conditionnel de la plupart des autres langages):

result = (y, x)[a > b]

ou dictionnaire explicitement construit:

result = {True: x, False: y}[a > b]

Une autre méthode (moins fiable), mais plus simple consiste à utiliser and et or opérateurs:

result = (a > b) and x or y

cependant cela ne fonctionnera pas si x serait False .

Une solution de contournement possible consiste à créer des listes et des tuples x et y comme suit:

result = ((a > b) and [x] or [y])[0]

ou:

result = ((a > b) and (x,) or (y,))[0]

Si vous travaillez avec des dictionnaires, au lieu d'utiliser un conditionnel ternaire, vous pouvez utiliser get(key, default) , par exemple:

shell = os.environ.get('SHELL', "/bin/sh")

Source: ?:




Il y a une option ternaire comme indiqué dans les autres réponses, mais vous pouvez aussi la simuler en utilisant "ou" si vous comparez avec une valeur booléenne ou none:

>>> a = False
>>> b = 5
>>> a or b
5

>>> a = None
>>> a or b
5



Pour Python 2.5 et plus récent, il existe une syntaxe spécifique:

[on_true] if [cond] else [on_false]

Dans les anciens Pythons, un opérateur ternaire n'est pas implémenté mais il est possible de le simuler.

cond and on_true or on_false

Cependant, il y a un problème potentiel qui, si la cond évaluée à True et on_true à False alors on_false est retourné au lieu de on_true . Si vous voulez ce comportement, la méthode est OK, sinon utilisez ceci:

{True: on_true, False: on_false}[cond is True] # is True, not == True

qui peut être enveloppé par:

def q(cond, on_true, on_false)
    return {True: on_true, False: on_false}[cond is True]

et utilisé de cette façon:

q(cond, on_true, on_false)

Il est compatible avec toutes les versions de Python.




In [1]: a = 1 if False else 0

In [2]: a
Out[2]: 0

In [3]: b = 1 if True else 0

In [4]: b
Out[4]: 1



expression1 si condition else expression2

>>> a = 1
>>> b = 2
>>> 1 if a > b else -1 
-1
>>> 1 if a > b else -1 if a < b else 0
-1



Plus une astuce qu'une réponse (pas besoin de répéter l'évidence pour la centième fois), mais je l'utilise parfois comme un raccourci oneliner dans de telles constructions:

if conditionX:
    print('yes')
else:
    print('nah')

, devient:

print('yes') if conditionX else print('nah')

Certains (beaucoup :) peuvent désapprouver comme non-pythonique (même, ruby-ish :), mais je trouve personnellement plus naturel - c'est-à-dire comment vous exprimer normalement, plus un peu plus attrayant visuellement dans de grands blocs de code.




Links