Python ont un opérateur conditionnel ternaire?

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

4616
demandé sur Devoted 2008-12-27 11:32:18

23 réponses

Oui, c'était , a ajouté dans la version 2.5.

La syntaxe est:

a if condition else b

D'abord condition est évalué, puis a ou b est retourné basé sur le booléen valeur de condition

Si condition évalue à vrai a est retourné, sinon b est retourné.

par exemple:

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

Note que les conditions sont un expression , pas un déclaration . Cela signifie que vous ne pouvez pas utiliser les assignations ou pass ou d'autres déclarations dans un conditionnel:

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

Dans un tel cas, vous devez utiliser une normale if instruction au lieu d'un conditionnel.


Gardez à l'esprit que c'est désapprouvé par certains Pythonistes pour plusieurs raisons:

  • l'ordre des arguments est différent de beaucoup d'autres langues (comme C, Ruby, Java, etc.), ce qui peut conduire à des bugs lorsque des personnes non familières avec le comportement "surprenant" de Python l'utilisent (ils peuvent inverser l'ordre).
  • certains le trouvent "lourd", car il va à l'encontre du flux normal de la pensée (en pensant d'abord à la condition et ensuite aux effets).
  • des raisons de style.

si vous avez de la difficulté à vous souvenir de l'ordre, alors rappelez-vous que si vous le lisez à haute voix, vous (presque) dites ce que vous voulez dire. Par exemple, x = 4 if b > 8 else 9 est lu à haute voix comme x will be 4 if b is greater than 8 otherwise 9 .

documentation officielle:

5487
répondu Vinko Vrsalovic 2018-04-25 10:43:11

vous pouvez indexer dans un tuple:

(falseValue, trueValue)[test]

test doit retourner vrai ou faux .

Il pourrait être plus sûr de toujours le mettre en œuvre comme:

(falseValue, trueValue)[test == True]

ou vous pouvez utiliser le intégré bool() pour assurer un booléen valeur:

(falseValue, trueValue)[bool(<expression>)]
616
répondu Landon Kuhn 2015-10-17 07:35:10

pour les versions antérieures à 2.5, il y a le truc:

[expression] and [on_true] or [on_false]

il peut donner de mauvais résultats quand on_true a une fausse valeur booléenne. 1

Bien qu'il ait l'avantage d'évaluer des expressions de gauche à droite, ce qui est plus clair à mon avis.

1. y a-t-il un équivalent de C?:" opérateur ternaire?

253
répondu James Brady 2014-01-13 07:16:48

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
162
répondu Simon Zimmermann 2012-01-25 12:30:56

à Partir de la documentation :

les expressions conditionnelles (parfois appelées "opérateurs ternaires") 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 retournée; sinon, y est évalué et sa valeur est retournée.

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

nouveau depuis la version 2.5.

108
répondu Michael Burr 2015-10-17 07:43:53

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 l'opérateur commun ?: et il est:

<expression1> if <condition> else <expression2>

qui est l'équivalent de:

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 avant 2.5):

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

où opérandes sont paresseusement évalué .

une autre façon est d'indexer un tuple (ce qui n'est pas compatible avec l'opérateur conditionnel de la plupart des autres langues):

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

ou explicitement construit dictionnaire:

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

une autre méthode (moins fiable), mais plus simple est d'utiliser and et or opérateurs:

result = (a > b) and x or y

cependant cela ne marchera pas si x serait False .

une solution possible est de faire x et y listes ou tuples comme dans le suivant:

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 de get(key, default) , par exemple:

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

Source: ?: en Python sur Wikipedia

82
répondu kenorb 2017-08-07 14:22:32

@

malheureusement, le

(falseValue, trueValue)[test]
La solution

n'a pas de comportement de court-circuit; ainsi falseValue et trueValue sont évaluées indépendamment de la condition. Ceci pourrait être sous-optimal ou même buggy (c.-à-d. les deux trueValue et falseValue pourraient ê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 est connu ;)), mais il introduit une incohérence entre remboursables et non remboursables objets. En outre, il ne résout pas le cas en utilisant des propriétés.

et ainsi de suite - le choix entre 3 solutions mentionnées est un compromis entre avoir la fonctionnalité de court-circuit, en utilisant au moins python 2.5 (IMHO pas un problème plus) et ne pas être enclin à" trueValue-évalue-to-false " erreurs.

74
répondu gorsky 2017-10-14 09:45:44

pour Python 2.5 et plus récent il y a une syntaxe spécifique:

[on_true] if [cond] else [on_false]

dans les vieux 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 cond évalue à True et on_true évalue à False puis 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.

49
répondu Paolo 2012-04-25 12:02:06

opérateur ternaire dans différents langages de programmation

ici, j'essaie juste de montrer une différence importante dans ternary operator entre deux langages de programmation.

opérateur ternaire en Javascript

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

opérateur ternaire en rubis

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 dans la programmation

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

Maintenant, vous pouvez voir la beauté du langage python. son très lisible et facile à entretenir.

41
répondu Simplans 2017-07-12 20:37:17

vous pourriez souvent trouver

cond and on_true or on_false

mais cela pose problème quand on_true = = 0

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

où l'on peut s'attendre 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
32
répondu Benoit Bertholon 2013-01-14 15:56:09

absolument, et c'est incroyablement facile à comprendre.

general syntax : first_expression if bool_expression_is_true else second_expression

Example: x= 3 if 3 > 2 else 4 
# assigns 3 to x if the boolean expression evaluates to true or 4 if it is false
29
répondu BattleDrum 2017-01-20 20:01:14

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

Oui. Extrait du fichier grammatical :

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

la partie de l'intérêt est:

or_test ['if' or_test 'else' test]

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

expression1 if expression2 else expression3

expression3 sera paresseusement évalué (c'est évaluée uniquement si expression2 est faux dans un booléen cadre.) 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:

noter que chaque if doit être suivi d'un else . La compréhension de la liste d'apprentissage et les expressions génératrices peuvent trouver cette 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

qui élève un 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 no - op dans la condition fausse) ou ce qui peut être prévu est d'utiliser expression2 comme un filtre-note que ce qui suit est Python juridique:

[expression1 for element in iterable if expression2]

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

syntaxe Alternative pour un cas plus étroit:

vous pouvez trouver un peu douloureux d'écrire ce qui suit:

expression1 if expression1 else expression2

expression1 devra être évalué deux fois avec l'utilisation ci-dessus. Il peut limiter la redondance si c'est simplement une variable locale. Cependant, un idiome pythonique courant et performant pour ce cas d'utilisation est d'utiliser le comportement de raccourcissement de or :

expression1 or expression2

qui est équivalent en sémantique. Notez que certains guides de style peut limiter cet usage pour des raisons de clarté - il ne pack beaucoup de sens dans très peu de syntaxe.

22
répondu Aaron Hall 2016-08-08 18:56:31

simulant l'opérateur Python ternary.

par exemple

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

sortie:

'b greater than a'
15
répondu Sasikiran Vaddi 2013-11-20 10:44:12

vous pouvez faire ceci :-

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

exemple: -

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

Ce serait impression "bizarre" si le nombre est impair ou "même" si le nombre est pair.


le résultat: - si la condition est true exp_1 est exécutée autrement exp_2 est exécutée.

Note :- 0 , Aucun , Faux , emptylist , emptyString est fausse (False). Et toute donnée autre que 0 est évaluée à True.

Voici comment ça marche:

si la condition [condition] devient" vraie " 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 .Ainsi, dans la déclaration ci-dessous ,

0 and exp

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

Dans

1 or exp

l'expression exp ne seront pas évalués depuis "ou" avec 1 sera toujours 1. Il ne sera donc pas nécessaire d'évaluer l'expression exp puisque le résultat sera 1 de toute façon . (compilateur méthodes d'optimisation).

mais dans le cas de

True and exp1 or exp2

la seconde expression exp2 ne sera pas évaluée car True and exp1 serait vrai quand exp1 n'est pas faux .

de la Même façon 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".


Note::- ce type de branchement utilisant" ou "et" et "ne peut être utilisé que lorsque l'expression_1 n'a pas de valeur de vérité de False (ou 0 ou None ou emptylist [ ] ou emptystring' '.) puisque si expression_1 devient False, 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 voulez toujours le faire fonctionner pour tous les cas indépendamment de ce que les valeurs de vérité exp_1 et exp_2 sont, faites ceci: -

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

10
répondu Natesh bhat 2017-08-20 07:48:54
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
9
répondu ox. 2014-05-07 13:02:06

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 froncer les sourcils sur elle comme unpythonic (même, ruby-ish :), mais je trouve personnellement plus naturel - c.-à-d. comment vous l'exprimeriez normalement, plus un peu plus visuellement attrayant dans de grands blocs de code.

9
répondu Todor 2016-05-23 19:16:26

ternary conditional operator permet simplement de tester une condition en une seule ligne en remplacement de la multiligne if-else ce qui rend le code compact.

syntaxe:

[on_true] si [expression] autre [on_false]

1-Méthode Simple d'utilisation de 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 à l'aide de n-uplets, Dictionnaire et 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-opérateur ternaire peut être écrit comme imbriqué si-sinon:

# 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")

approche ci-dessus peut être écrit comme:

# 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
9
répondu Ali Hallaji 2018-04-04 14:02:17

Oui, vous pouvez l'utiliser de cette façon :

is_fat = True
state = "fat" if is_fat else "not fat"

plus d'informations à propos de ternary conditional operator

8
répondu Daniel Taub 2017-06-10 13:14:08

Oui.

>>> b = (True if 5 > 4 else False)
>>> print b
True
4
répondu Alejandro Blasco 2016-03-16 16:36:22

Oui:

disons que vous voulez donner à la variable x une certaine valeur si un certain bool est vrai et de même

X = 5 Si autre chose x =10

X = [valeur] si [si c'est la première vraie valeur évalue] autre [autre valeur évalue]

2
répondu Elad Goldenberg 2018-05-14 06:25:11
Syntaxe

: L'opérateur ternaire sera donné comme suit:

[on_true] if [expression] else [on_false]

E. g

x, y = 25, 50
big = x if x < y else y
print(big)
2
répondu Saurabh Chandra Patel 2018-07-31 20:23:58

il y a une option ternaire comme indiqué dans d'autres réponses, mais vous pouvez également simuler en utilisant "ou" si vous vérifiez contre un booléen ou Aucune valeur:

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

>>> a = None
>>> a or b
5
1
répondu Meow 2016-12-08 19:05:13

si la variable est définie et que vous voulez vérifier si elle a une valeur, vous pouvez juste 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)

sortira

no Input
no Input
no Input
hello
['Hello']
True
1
répondu ewwink 2018-04-26 16:22:58