Python a-t-il un opérateur conditionnel ternaire?


6050

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


149
Dans la documentation officielle de Python 3.0 référencée dans un commentaire ci-dessus, cela est appelé "expressions_conditionnelles" et est très cryptiquement défini. Cette documentation n'inclut même pas le terme "ternaire", donc vous auriez du mal à le trouver via Google à moins que vous ne sachiez exactement quoi chercher. La documentation de la version 2 est un peu plus utile et inclut un lien vers "PEP 308" , qui inclut beaucoup de contexte historique intéressant lié à cette question.
nobar

26
le "ternaire" (ayant trois entrées) est une propriété conséquente de cette impulsion, pas une propriété déterminante du concept. par exemple: SQL a case [...] { when ... then ...} [ else ... ] endun effet similaire mais pas du tout ternaire.
user313114

10
également la section 6.5.15 de la norme ISO / IEC 9899 (la norme du langage de programmation C) l'appelle "l'opérateur conditionnel"
user313114

9
Wikipédia en parle en détail dans l'article " ?: ".
HelloGoodbye

9
Dans les années qui ont suivi le commentaire de nobar, la documentation des expressions conditionnelles a été mise à jour pour indiquer les expressions conditionnelles (parfois appelées «opérateur ternaire») ...
Scott Martin

Réponses:


7047

Oui, il a été ajouté dans la version 2.5. La syntaxe de l'expression est:

a if condition else b

Le premier conditionest évalué, puis exactement l'un des deux aou best évalué et renvoyé en fonction de la valeur booléenne de condition. Si conditionévalue à True, alors aest évalué et renvoyé mais best ignoré, ou bien quand best évalué et renvoyé mais aignoré.

Cela permet de court-circuiter car quand conditionest vrai seulement aest évalué et bn'est pas évalué du tout, mais quand conditionest faux seulement best évalué et an'est pas évalué du tout.

Par exemple:

>>> 'true' if True else 'false'
'true'
>>> 'true' if False else 'false'
'false'

Notez que les conditions sont une expression , pas une instruction . Cela signifie que vous ne pouvez pas utiliser d'instructions d'affectation passou d'autres instructions dans une expression conditionnelle :

>>> pass if False else x = 3
  File "<stdin>", line 1
    pass if False else x = 3
          ^
SyntaxError: invalid syntax

Vous pouvez cependant utiliser des expressions conditionnelles pour affecter une variable comme ceci:

x = a if True else b

Considérez l'expression conditionnelle comme une commutation entre deux valeurs. C'est très utile lorsque vous êtes dans une situation «une valeur ou une autre», mais cela ne fait pas grand-chose d'autre.

Si vous devez utiliser des instructions, vous devez utiliser une if instruction normale au lieu d'une expression conditionnelle .


Gardez à l'esprit qu'il est mal vu par certains Pythonistes pour plusieurs raisons:

  • L'ordre des arguments est différent de celui de l' condition ? a : bopérateur ternaire classique de nombreux autres langages (tels que C, C ++, Go, Perl, Ruby, Java, Javascript, etc.), ce qui peut conduire à des bugs lorsque les gens ne connaissent pas Python " un comportement "surprenant" l'utilise (ils peuvent inverser l'ordre des arguments).
  • Certains le trouvent "peu maniable", car il va à l'encontre du flux normal de la pensée (penser d'abord à la condition puis aux effets).
  • Raisons stylistiques. (Bien que le «inline if» puisse être vraiment utile et rendre votre script plus concis, il complique vraiment votre code)

Si vous avez du mal à vous souvenir de la commande, n'oubliez pas que lorsque vous lisez à haute voix, vous dites (presque) ce que vous voulez dire. Par exemple, x = 4 if b > 8 else 9est lu à haute voix comme x will be 4 if b is greater than 8 otherwise 9.

Documentation officielle:


269
L'ordre peut sembler étrange pour les codeurs, mais cela f(x) = |x| = x if x > 0 else -xsemble très naturel aux mathématiciens. Vous pouvez également le comprendre comme le fait A dans la plupart des cas, sauf lorsque C, alors vous devriez faire B à la place ...
yota

121
Soyez prudent avec l'ordre des opérations lorsque vous l'utilisez. Par exemple, la ligne z = 3 + x if x < y else y. Si x=2et y=1, vous pourriez vous attendre à ce que cela donne 4, mais cela donnerait en fait 1. z = 3 + (x if x > y else y)est l'utilisation correcte.
Kal Zekdor

11
Le point était que si vous souhaitez effectuer des évaluations supplémentaires après l' évaluation du conditionnel, comme l'ajout d'une valeur au résultat, vous devrez soit ajouter l'expression supplémentaire des deux côtés ( z = 3 + x if x < y else 3 + y), soit regrouper le conditionnel ( z = 3 + (x if x < y else y)ou z = (x if x < y else y) + 3)
Kal Zekdor

4
@MrGeek, je vois ce que vous voulez dire, donc vous imbriqueriez essentiellement les opérations: `" foo "if Bool else (" bar "if Bool else" foobar ")`
Dimesio

3
Les programmeurs ont encore plus besoin d'une formulation correcte et précise que le mathématicien, car en mathématiques il y a toujours recours aux concepts sous-jacents. Un argument convaincant est l'opérateur%, imiter la façon dont "mod" est utilisé en mathématiques aurait été un désastre. Alors non, je n'accepte pas votre argument. C'est comme adhérer aux unités impériales. Groetjes Albert
Albert van der Horst

799

Vous pouvez indexer dans un tuple:

(falseValue, trueValue)[test]

testdoit renvoyer Vrai ou Faux .
Il pourrait être plus sûr de toujours l'implémenter comme:

(falseValue, trueValue)[test == True]

ou vous pouvez utiliser la fonction intégrée bool()pour garantir une valeur booléenne :

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

591
Notez que celle-ci évalue toujours tout, tandis que la construction if / else n'évalue que l'expression gagnante.
SilverbackNet

117
(lambda: print("a"), lambda: print("b"))[test==true]()
Dustin Getz

15
Il convient de noter que ce qui se trouve dans le []s peut être une expression arbitraire. En outre, pour des raisons de sécurité, vous pouvez explicitement tester la véracité en écrivant [bool(<expression>)]. La bool()fonction existe depuis la version 2.2.1.
martineau

12
J'ai fait une astuce similaire - seulement une ou deux fois, mais je l'ai fait - en indexant dans un dictionnaire avec Trueet Falsecomme clés: {True:trueValue, False:falseValue}[test] je ne sais pas si c'est moins efficace, mais cela évite au moins le tout débat "élégant" contre "laid". Il n'y a aucune ambiguïté que vous ayez affaire à un booléen plutôt qu'à un int.
JDM


338

Pour les versions antérieures à 2.5, voici l'astuce:

[expression] and [on_true] or [on_false]

Il peut donner des résultats erronés lorsqu'il on_true a une fausse valeur booléenne. 1
Bien qu'il présente l'avantage d'évaluer les expressions de gauche à droite, ce qui est plus clair à mon avis.

1. Y a-t-il un équivalent d'opérateur ternaire C? »:«?


67
Le remède est d'utiliser (test et [true_value] ou [false_value]) [0], ce qui évite ce piège.
ThomasH

6
L'opérateur ternaire s'exécute généralement plus rapidement (parfois de 10 à 25%).
volcan

7
@volcano Avez-vous une source pour moi?
OrangeTux

4
@OrangeTux Voici le code démonté . L'utilisation de la méthode suggérée par ThomasH serait encore plus lente.
mbomb007

265

<expression 1> if <condition> else <expression 2>

a = 1
b = 2

1 if a > b else -1 
# Output is -1

1 if a > b else -1 if a < b else 0
# Output is -1

83
Celui-ci souligne l'intention principale de l'opérateur ternaire: la sélection de la valeur. Il montre également que plus d'un ternaire peut être enchaîné en une seule expression.
Roy Tinker

6
@Craig, je suis d'accord, mais il est également utile de savoir ce qui se passera en l'absence de parenthèses. Dans le vrai code, j'aurais aussi tendance à insérer des parens explicites.
Jon Coombs du

159

De la documentation :

Les expressions conditionnelles (parfois appelées «opérateur ternaire») ont la priorité la plus basse de toutes les opérations Python.

L'expression x if C else yévalue d'abord la condition, C ( pas x ); si C est vrai, x est évalué et sa valeur est renvoyée; sinon, y est évalué et sa valeur est renvoyée.

Voir PEP 308 pour plus de détails sur les expressions conditionnelles.

Nouveau depuis la version 2.5.


120

Un opérateur pour une expression conditionnelle en Python a été ajouté en 2006 dans le cadre de la proposition d'amélioration Python 308 . Sa forme diffère de celle de l' ?:opérateur courant 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

Autre syntaxe utilisable (compatible avec les versions antérieures à 2.5):

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

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

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

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

ou dictionnaire explicitement construit:

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

Un autre (moins fiable), mais plus simple méthode consiste à utiliser andet les oropérateurs:

result = (a > b) and x or y

mais cela ne fonctionnera pas si ce xserait le cas False.

Une solution possible est de faire xet des ylistes ou tuples 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 profiter get(key, default), par exemple:

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

Source: ?: En Python sur Wikipedia


1
result = {1: x, 0: y}[a > b]est une autre variante possible ( Trueet Falsesont en fait des entiers avec des valeurs 1et 0)
Walter Tross

98

Malheureusement, le

(falseValue, trueValue)[test]

la solution n'a pas de comportement de court-circuit; ainsi les deux falseValueet trueValuesont évalués quelle que soit la condition. Cela pourrait être sous-optimal ou même bogué (c'est-à-dire les deux trueValueet falseValuepourrait être des méthodes et avoir des effets secondaires).

Une solution à ce problème serait

(lambda: falseValue, lambda: trueValue)[test]()

(exécution retardée jusqu'à ce que le gagnant soit connu;)), mais il introduit une incohérence entre les objets appelables et non appelables. De plus, cela ne résout pas le cas lors de l'utilisation des propriétés.

Et donc l'histoire continue - choisir entre 3 solutions mentionnées est un compromis entre avoir la fonction de court-circuit, utiliser au moins Зython 2.5 (à mon humble avis plus un problème) et ne pas être sujet aux erreurs " trueValue-évalue-à-faux" .


2
Bien que le tuple de lambdas fonctionne, cela prend environ 3 fois plus de temps que l'opérateur ternaire. Ce n'est susceptible d'être une idée raisonnable que s'il peut remplacer une longue chaîne de if else if.
Perkins

72

Opérateur ternaire dans différents langages de programmation

Ici, j'essaie juste de montrer une différence importante ternary operatorentre quelques langages de programmation.

Opérateur ternaire en Javascript

var a = true ? 1 : 0;
# 1
var b = false ? 1 : 0;
# 0

Opérateur ternaire à Ruby

a = true ? 1 : 0
# 1
b = false ? 1 : 0
# 0

Opérateur ternaire à Scala

val a = true ? 1 | 0
# 1
val b = false ? 1 | 0
# 0

Opérateur ternaire en programmation R

a <- if (TRUE) 1 else 0
# 1
b <- if (FALSE) 1 else 0
# 0

Opérateur ternaire en Python

a = 1 if True else 0
# 1
b = 1 if False else 0
# 0


5
Cela peut sembler opiniâtre; mais ce qu'il dit essentiellement, c'est que la syntaxe Python est susceptible d'être comprise par une personne qui n'a jamais vu d'opérateur ternaire, alors que très peu de gens comprendront la syntaxe la plus habituelle à moins qu'on ne leur ait d'abord dit ce qu'elle signifie.
fralau

1
Algol68: a = .if. .vrai. .puis. 1. Sinon. 0 .fi. Cela peut s'exprimer également a = (. True. | 1 | 0) Comme d'habitude Algol68 est une amélioration par rapport à ses successeurs.
Albert van der Horst

63

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 elle est condévaluée à Trueet on_trueEquivaut à Falsepuis on_falseest 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.


2
Le comportement n'est pas identique - q("blob", on_true, on_false)renvoie on_false, tandis que on_true if cond else on_falserenvoie on_true. Une solution de contournement consiste à remplacer condpar cond is not Nonedans ces cas, bien que ce ne soit pas une solution parfaite.

5
Pourquoi pas à la bool(cond)place de cond is True? Le premier vérifie la véracité de cond, le second vérifie l'égalité du pointeur avec l' Trueobjet. Comme l'a souligné @AndrewCecil, "blob"c'est vrai mais ça is not True.
Jonas Kölker

Wow, ça a l'air vraiment hacky! :) Techniquement, vous pouvez même écrire [on_false, on_True][cond is True]pour que l'expression devienne plus courte.
Arseny

Il n'y a pas de court-circuit dans cette réponse. Si on_true et on_false coûtent cher à appeler, c'est une mauvaise réponse.
Hucker

44

Vous pourriez souvent trouver

cond and on_true or on_false

mais cela pose 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

38

Python a-t-il un opérateur conditionnel ternaire?

Oui. À partir 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

expression3sera évalué paresseusement (c'est-à-dire évalué uniquement si expression2est faux dans un contexte booléen). Et en raison de la définition récursive, vous pouvez les enchaîner indéfiniment (même si cela peut ê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 ifdoit être suivi d'un else. Les personnes qui apprennent la compréhension de listes et les expressions de générateur peuvent trouver cela 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 un SyntaxError: invalid syntax. Donc, ce qui précède est soit un morceau de logique incomplet (peut-être que l'utilisateur s'attend à un no-op dans la fausse condition) ou ce qui peut être prévu est d'utiliser expression2 comme filtre - note que ce qui suit est Python légal:

[expression1 for element in iterable if expression2]

expression2fonctionne 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 trouverez peut-être un peu pénible d'écrire ce qui suit:

expression1 if expression1 else expression2

expression1devra être évalué 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 orle comportement de raccourci de:

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é - ils contiennent beaucoup de sens dans très peu de syntaxe.


1
expression1 or expression2étant similaire et avec les mêmes inconvénients / positifs qu'en expression1 || expression2javascript
JSDBroughton

1
Merci, @selurvedu - cela peut prêter à confusion jusqu'à ce que vous compreniez bien. J'ai appris à la dure, donc votre chemin pourrait ne pas être aussi difficile. ;) Utiliser if sans else, à la fin d'une expression de générateur ou de compréhension de liste, filtrera l'itérable. À l'avant, c'est une opération conditionnelle ternaire, et nécessite le reste. À votre santé!!
Aaron Hall

@AaronHall Bien que votre utilisation de la métasyntaxe expressionNpour toutes les instances soit cohérente, il pourrait être plus facile à comprendre avec une dénomination qui distingue l'expression de test conditionnelle des deux expressions de résultat; par exemple result1 if condition else result2. Cela est particulièrement évident lors de l' imbrication (aka enchaînant): result1 if condition1 else result2 if condition2 else result3. Vous voyez à quel point cela se lit mieux?
tchrist

@tchrist merci pour la revue - si vous regardez l'historique des révisions, ce post a actuellement deux révisions. La plupart de mes autres réponses, en particulier les meilleures, ont été revues encore et encore. Cette réponse n'attire jamais mon attention parce que le statut du wiki communautaire ne me donne aucun crédit pour le contenu, et donc je ne vois jamais de votes dessus. Comme je n'ai pas vraiment le temps pour un montage sur ce sujet en ce moment, Frog sait quand cela reviendra à mon attention à l'avenir. Je peux voir que vous avez modifié la première réponse, alors n'hésitez pas à emprunter / citer mon matériel de ce post dans celui-ci (et citez-moi si c'est à propos!)
Aaron Hall

23

Simulation de l'opérateur ternaire python.

Par exemple

a, b, x, y = 1, 2, 'a greather than b', 'b greater than a'
result = (lambda:y, lambda:x)[a > b]()

production:

'b greater than a'

Pourquoi pas simplement result = (y, x)[a < b]Pourquoi utilisez-vous la lambdafonction ?
Grijesh Chauhan

5
@GrijeshChauhan Parce que sur les expressions "compliées", par exemple impliquant un appel de fonction, etc., cela serait exécuté dans les deux cas. Cela pourrait ne pas être souhaité.
glglgl

20

L'opérateur conditionnel ternaire permet simplement de tester une condition sur une seule ligne en remplaçant le multiligne if-else rendant le code compact.

Syntaxe:

[on_true] if [expression] else [on_false]

1- Méthode simple pour utiliser l'opérateur ternaire:

# Program to demonstrate conditional operator
a, b = 10, 20
# Copy value of a in min if a < b else copy b
min = a if a < b else b
print(min)  # Output: 10

2- Méthode directe d'utilisation des tuples, du dictionnaire et du lambda:

# Python program to demonstrate ternary operator
a, b = 10, 20
# Use tuple for selecting an item
print( (b, a) [a < b] )
# Use Dictionary for selecting an item
print({True: a, False: b} [a < b])
# lamda is more efficient than above two methods
# because in lambda  we are assure that
# only one expression will be evaluated unlike in
# tuple and Dictionary
print((lambda: b, lambda: a)[a < b]()) # in output you should see three 10

3- L'opérateur ternaire peut s'écrire comme imbriqué if-else:

# Python program to demonstrate nested ternary operator
a, b = 10, 20
print ("Both a and b are equal" if a == b else "a is greater than b"
        if a > b else "b is greater than a")

L'approche ci-dessus peut s'écrire:

# Python program to demonstrate nested ternary operator
a, b = 10, 20
if a != b:
    if a > b:
        print("a is greater than b")
    else:
        print("b is greater than a")
else:
    print("Both a and b are equal") 
# Output: b is greater than a

1
Notez que l'opérateur ternaire est plus petit (en mémoire) et plus rapide que le si imbriqué. De plus, votre imbriqué if-elsen'est pas réellement une réécriture de l'opérateur ternaire et produira une sortie différente pour les valeurs sélectionnées de a et b (en particulier si l'un est un type qui implémente une __ne__méthode étrange ).
Perkins

19

tu peux le faire :-

[condition] and [expression_1] or [expression_2] ;

Exemple:-

print(number%2 and "odd" or "even")

Cela afficherait "impair" si le nombre est impair ou "pair" si le nombre est pair.


Le résultat :- Si la condition est vraie, exp_1 est exécutée, sinon exp_2 est exécutée.

Remarque :- 0, None, False, emptylist, emptyString est évalué comme False. Et toutes les données autres que 0 sont évaluées à True.

Voici comment ça fonctionne:

si la condition [condition] devient "True", alors expression_1 sera évaluée mais pas expression_2. Si nous "et" quelque chose avec 0 (zéro), le résultat sera toujours fasle. Donc dans l'instruction ci-dessous,

0 and exp

L'expression exp ne sera pas évaluée du tout car "et" avec 0 seront toujours évalués à zéro et il n'est pas nécessaire d'évaluer l'expression. C'est ainsi que le compilateur lui-même fonctionne, dans toutes les langues.

Dans

1 or exp

l'expression exp ne sera pas du tout évaluée car "ou" avec 1 sera toujours égal à 1. Il ne sera donc pas la peine d'évaluer l'expression exp puisque le résultat sera de toute façon 1. (méthodes d'optimisation du compilateur).

Mais en cas de

True and exp1 or exp2

La deuxième expression exp2 ne sera pas évaluée car True and exp1 serait True lorsque exp1 n'est pas fausse.

De même dans

False and exp1 or exp2

L'expression exp1 ne sera pas évaluée car False équivaut à écrire 0 et à faire "et" avec 0 serait 0 lui-même mais après exp1 puisque "ou" est utilisé, il évaluera l'expression exp2 après "ou".


Remarque: - Ce type de ramification utilisant "ou" et "et" ne peut être utilisé que lorsque l'expression_1 n'a pas la valeur Truth False (ou 0 ou None ou emptylist [] ou emptystring ''.) Car si expression_1 devient Faux, alors l'expression_2 sera évaluée en raison de la présence "ou" entre exp_1 et exp_2.

Dans le cas où vous souhaitez toujours le faire fonctionner pour tous les cas, quelles que soient les valeurs de vérité exp_1 et exp_2, procédez comme suit: -

[condition] and ([expression_1] or 1) or [expression_2] ;


Si vous souhaitez utiliser dans le contexte de x = [condition] and ([expression_1] or 1) or [expression_2]et la expression_1valeur false, xsera 1, non expression_1. Utilisez la réponse acceptée.
moi

18

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 raccourci oneliner dans de telles constructions:

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

, devient:

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

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


5
Je préfère print( 'yes' if conditionX else 'nah' )ta réponse. :-)
frederick99

C'est si vous voulez print()dans les deux cas - et ça a l'air un peu plus pythonique, je dois admettre :) Mais que se passe-t-il si les expressions / fonctions ne sont pas les mêmes - comme print('yes') if conditionX else True- pour obtenir le print()seul en véritéconditionX
Todor Minakov

Pour ajouter à la remarque de Frederick99, une autre raison à éviter print('yes') if conditionX else print('nah')est qu'elle donne une SyntaxError en Python2.
Thierry Lathuille

La seule raison pour laquelle il donne une erreur de syntaxe est que, dans Python 2, print est une déclaration - print "yes", tandis que dans Python 3, c'est une fonction - print("yes"). Cela peut être résolu soit en l'utilisant comme une déclaration, soit mieux - from future import print_function.
Todor Minakov

18
a if condition else b

Mémorisez simplement cette pyramide si vous avez du mal à vous souvenir:

     condition
  if           else
a                   b 

14

L'une des alternatives à l' expression conditionnelle de Python

"yes" if boolean else "no"

est le suivant:

{True:"yes", False:"no"}[boolean]

qui a la belle extension suivante:

{True:"yes", False:"no", None:"maybe"}[boolean_or_none]

L'alternative la plus courte reste:

("no", "yes")[boolean]

mais il n'y a pas d'alternative à

yes() if boolean else no()

si vous voulez éviter l'évaluation de yes() et no() , parce que dans

(no(), yes())[boolean]  # bad

les deux no()et yes()sont évalués.


10

De nombreux langages de programmation dérivés Cont généralement la syntaxe d'opérateur conditionnel ternaire suivante:

<condition> ? <expression1> : <expression2>

Dans un premier temps , le Python B enevolent D ictator F ou L IFE (je veux dire Guido van Rossum, bien sûr) a rejeté (comme le style non Pythonic), car il est assez difficile à comprendre pour les gens non habitués à la Clangue. En outre, le signe deux-points :a déjà de nombreuses utilisations Python. Après l' approbation du PEP 308 , il a Pythonfinalement reçu sa propre expression conditionnelle de raccourci (ce que nous utilisons maintenant):

<expression1> if <condition> else <expression2>

Donc, tout d'abord, il évalue la condition. S'il revient True, expression1 sera évaluée pour donner le résultat, sinon expression2 sera évaluée. En raison de la mécanique d' évaluation paresseuse - une seule expression sera exécutée.

Voici quelques exemples (les conditions seront évaluées de gauche à droite):

pressure = 10
print('High' if pressure < 20 else 'Critical')

# Result is 'High'

Les opérateurs ternaires peuvent être enchaînés en série:

pressure = 5
print('Normal' if pressure < 10 else 'High' if pressure < 20 else 'Critical')

# Result is 'Normal'

Le suivant est le même que le précédent:

pressure = 5

if pressure < 20:
    if pressure < 10:
        print('Normal')
    else:
        print('High')
else:
    print('Critical')

# Result is 'Normal'

J'espère que cela t'aides.


10

Comme déjà répondu, oui il y a un opérateur ternaire en python:

<expression 1> if <condition> else <expression 2>

Information additionnelle:

Si tel<expression 1> est le cas, vous pouvez utiliser l' évaluation à court terme :

a = True
b = False

# Instead of this:
x = a if a else b

# You could use Short-cirquit evaluation:
x = a or b

PS: Bien sûr, une évaluation de court-circuit n'est pas un opérateur ternaire mais souvent le ternaire est utilisé dans les cas où le court-circuit serait suffisant.


1
Votez pour cette short-circuitévaluation.
CodeIt

7

OUI, python a un opérateur ternaire, voici la syntaxe et un exemple de code pour le démontrer :)

#[On true] if [expression] else[On false]
# if the expression evaluates to true then it will pass On true otherwise On false


a= input("Enter the First Number ")
b= input("Enter the Second Number ")

print("A is Bigger") if a>b else print("B is Bigger")

J'ai ajouté un exemple de déclaration d'une ligne pour vérifier quel nombre est grand pour le développer davantage
PythonLover

1
printn'est vraiment pas un bon choix, car cela donnera une SyntaxError en Python2.
Thierry Lathuille

@Thierry Lathuille ici j'ai utilisé la fonction print () et non la déclaration print, la fonction print est pour Python 3 tandis que la déclaration print est pour Python 2
PythonLover

La question a déjà été posée sur SO, essayez-la avec Python 2 et vous verrez par vous-même. 'print (' hello ') est une syntaxe parfaitement valide dans Python 2.7, mais la façon dont il est analysé fait que votre code ci-dessus lance une SyntaxError.
Thierry Lathuille

2

Python a une forme ternaire pour les affectations; cependant, il peut y avoir une forme encore plus courte que les gens devraient connaître.

Il est très courant de devoir attribuer à une variable une valeur ou une autre en fonction d'une condition.

>>> li1 = None
>>> li2 = [1, 2, 3]
>>> 
>>> if li1:
...     a = li1
... else:
...     a = li2
...     
>>> a
[1, 2, 3]

^ C'est la forme longue pour faire de telles tâches.

Voici la forme ternaire. Mais ce n'est pas la manière la plus succincte - voir le dernier exemple.

>>> a = li1 if li1 else li2
>>> 
>>> a
[1, 2, 3]
>>> 

Avec Python, vous pouvez simplement utiliser orpour d'autres affectations.

>>> a = li1 or li2
>>> 
>>> a
[1, 2, 3]
>>> 

Ce qui précède fonctionne depuis li1est Noneet l'interp traite cela comme faux dans les expressions logiques. L'interp continue ensuite et évalue la deuxième expression, qui n'est pas Noneet ce n'est pas une liste vide - elle est donc affectée à a.

Cela fonctionne également avec des listes vides. Par exemple, si vous souhaitez attribuer la aliste contenant des éléments.

>>> li1 = []
>>> li2 = [1, 2, 3]
>>> 
>>> a = li1 or li2
>>> 
>>> a
[1, 2, 3]
>>> 

Sachant cela, vous pouvez simplement de telles affectations chaque fois que vous les rencontrez. Cela fonctionne également avec les chaînes et autres itérables. Vous pouvez attribuer la achaîne qui n'est pas vide.

>>> s1 = ''
>>> s2 = 'hello world'
>>> 
>>> a = s1 or s2
>>> 
>>> a
'hello world'
>>> 

J'ai toujours aimé la syntaxe C ternaire, mais Python va plus loin!

Je comprends que certains puissent dire que ce n'est pas un bon choix stylistique car il repose sur des mécanismes qui ne sont pas immédiatement apparents pour tous les développeurs. Personnellement, je ne suis pas d'accord avec ce point de vue. Python est un langage riche en syntaxe avec de nombreuses astuces idiomatiques qui ne sont pas immédiatement visibles pour le dabler. Mais plus vous apprenez et comprenez la mécanique du système sous-jacent, plus vous l'appréciez.


1

D'autres réponses parlent correctement de l'opérateur ternaire Python. Je voudrais compléter en mentionnant un scénario pour lequel l'opérateur ternaire est souvent utilisé mais pour lequel il existe un meilleur idiome. Il s'agit du scénario d'utilisation d'une valeur par défaut.

Supposons que nous voulons utiliser option_valueune valeur par défaut si elle n'est pas définie:

run_algorithm(option_value if option_value is not None else 10)

ou simplement

run_algorithm(option_value if option_value else 10)

Cependant, une meilleure solution consiste simplement à écrire

run_algorithm(option_value or 10)

-2

si la variable est définie et que vous voulez vérifier si elle a une valeur, vous pouvez simplement a or b

def test(myvar=None):
    # shorter than: print myvar if myvar else "no Input"
    print myvar or "no Input"

test()
test([])
test(False)
test('hello')
test(['Hello'])
test(True)

affichera

no Input
no Input
no Input
hello
['Hello']
True

1
Bien qu'utile pour des problèmes similaires, ce n'est pas une condition ternaire. Cela fonctionne pour remplacer x if x else y, mais pas x if z else y.
Perkins

-2

Une bonne façon de chaîner plusieurs opérateurs:

f = lambda x,y: 'greater' if x > y else 'less' if y > x else 'equal'

array = [(0,0),(0,1),(1,0),(1,1)]

for a in array:
  x, y = a[0], a[1]
  print(f(x,y))

# Output is:
#   equal,
#   less,
#   greater,
#   equal

-2

Je trouve lourde la syntaxe python par défaut val = a if cond else b, donc parfois je fais ceci:

iif = lambda (cond, a, b): a if cond else b
# so I can then use it like:
val = iif(cond, a, b)

Bien sûr, il a l'inconvénient d'évaluer toujours les deux côtés (a et b), mais la syntaxe est beaucoup plus claire pour moi


Cela semble être deux fois plus de travail, plus d'utilisation de la RAM et plus obscurci que la simple val = a if cond else bdéclaration.
eatsfood

-3
is_spacial=True if gender = "Female" else (True if age >= 65 else False)

**

il peut être imbriqué selon vos besoins. bonne chance

**

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.