Python ont un opérateur conditionnel ternaire?
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:
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>)]
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.
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
à 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.
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
@
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.
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.
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.
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
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
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.
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'
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] ;
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
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.
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
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
Oui.
>>> b = (True if 5 > 4 else False)
>>> print b
True
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]
: 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)
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
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