Si Python n'a pas d'opérateur conditionnel ternaire, est-il possible de le simuler en utilisant d'autres constructions de langage?
Oui, c'était ajouté dans la version 2.5. La syntaxe de l'expression est la suivante:
a if condition else b
La première variable condition
est évaluée, puis l'une ou l'autre des variables a
ou b
est évaluée et renvoyée en fonction de la valeur Boolean de condition
. Si condition
est évalué à True
, alors a
est évalué et renvoyé, mais b
est ignoré ou sinon, lorsque b
est évalué et renvoyé mais a
est ignoré.
Cela permet de court-circuiter car lorsque condition
est vrai, seul a
est évalué et b
n'est pas du tout évalué, mais lorsque condition
est faux, seul b
est évalué et a
n'est pas du tout évalué.
Par exemple:
>>> 'true' if True else 'false'
'true'
>>> 'true' if False else 'false'
'false'
Notez que les éléments conditionnels sont un expression, pas un instruction. Cela signifie que vous ne pouvez pas utiliser d'instructions d'affectation, ni pass
ni 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
Dans un tel cas, vous devez utiliser un if
statement normal au lieu d'un expression conditionnel.
N'oubliez pas que certains pythonistes la désapprouvent pour plusieurs raisons:
condition ? a : b
classique dans de nombreux autres langages (tels que C, C++, Go, Perl, Ruby, Java, Javascript, etc.), ce qui peut entraîner des erreurs lorsque les utilisateurs ne sont pas familiers avec Python. le comportement "surprenant" l'utilise (ils peuvent inverser l'ordre des arguments).Si vous ne parvenez pas à vous rappeler l'ordre, souvenez-vous que, lorsqu'il est lu à haute voix, vous dites (presque) ce que vous voulez dire. Par exemple, x = 4 if b > 8 else 9
est lu à haute voix sous la forme 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 renvoyer True ou False.
Il pourrait être plus sûr de toujours le mettre en œuvre de la manière suivante:
(falseValue, trueValue)[test == True]
ou vous pouvez utiliser la fonction bool()
pour vous assurer que Boolean value:
(falseValue, trueValue)[bool(<expression>)]
Pour les versions antérieures à la version 2.5, le truc est le suivant:
[expression] and [on_true] or [on_false]
Cela peut donner des résultats erronés lorsque on_true
a une fausse valeur booléenne.1
Bien qu'il ait l'avantage d'évaluer les expressions de gauche à droite, ce qui est plus clair à mon avis.
expression1 if 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
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 (not 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.
Un opérateur pour une expression conditionnelle en Python a été ajouté en 2006 dans le cadre de Python Enhancement Proposition 308 . Sa forme diffère de l'opérateur ?:
commun et c'est:
<expression1> if <condition> else <expression2>
qui équivaut à:
if <condition>: <expression1> else: <expression2>
Voici un exemple:
result = x if a > b else y
Une autre syntaxe utilisable (compatible avec les versions antérieures à la 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 ne correspond pas à 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]
Une autre méthode (moins fiable), mais plus simple, consiste à utiliser les opérateurs and
et or
:
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 ou 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 utilisez des dictionnaires, au lieu d'utiliser un conditionnel ternaire, vous pouvez tirer parti de get(key, default)
, par exemple:
Shell = os.environ.get('Shell', "/bin/sh")
Source: ?: En Python sur Wikipedia
@up:
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. Cela peut être sous-optimal ou même bogué (c’est-à-dire que trueValue et falseValue peuvent être des méthodes et avoir des effets secondaires).
Une solution à cela serait
(lambda: falseValue, lambda: trueValue)[test]()
(exécution différée jusqu'à ce que le gagnant soit connu;)), mais introduit une incohérence entre les objets appelables et non appelables. De plus, cela ne résout pas le problème lorsque vous utilisez des propriétés.
Et ainsi va l'histoire - le choix entre les 3 solutions mentionnées est un compromis entre avoir la fonctionnalité de court-circuit, utiliser au moins python 2.5 (IMHO n'est plus un problème) et ne pas être enclin à "trueValue-evaluates-to-false" les erreurs.
Pour Python 2.5 et les versions plus récentes, il existe une syntaxe spécifique:
[on_true] if [cond] else [on_false]
Dans les Pythons plus anciens, 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 existe un problème potentiel qui, si cond
est évalué à True
et on_true
est évalué à False
, alors on_false
est renvoyé au lieu de on_true
. Si vous voulez que ce comportement la méthode soit OK, sinon utilisez ceci:
{True: on_true, False: on_false}[cond is True] # is True, not == True
qui peut être emballé 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.
Ici, je tente simplement de montrer une différence importante dans ternary operator
entre quelques 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 en 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
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ù vous vous attendriez 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
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
expression3
sera évalué paresseusement (c’est-à-dire qu’il n’est évalué que si expression2
est faux dans un contexte booléen). Et à cause de la définition récursive, vous pouvez les chaî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
Notez que chaque if
doit être suivi d'un else
. Les personnes apprenant la compréhension des listes 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 une 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 élément de logique incomplet (peut-être que l'utilisateur s'attend à un non-fonctionnement dans la condition fausse) ou bien ce que l'on peut vouloir utiliser est d'utiliser l'expression2 comme filtre. Python légal:
[expression1 for element in iterable if expression2]
expression2
fonctionne comme un filtre pour la compréhension de la liste et est not un opérateur conditionnel ternaire.
Vous trouverez peut-être un peu pénible d’écrire ce qui suit:
expression1 if expression1 else expression2
expression1
devra être évalué deux fois avec l'utilisation ci-dessus. Cela 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 consiste à utiliser le comportement de raccourci de or
:
expression1 or expression2
ce qui est équivalent en sémantique. Notez que certains guides de style peuvent limiter cet usage pour des raisons de clarté - il contient beaucoup de signification dans très peu de syntaxe.
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]()
sortie:
'b greater than a'
L'opérateur conditionnel ternaire permet simplement de tester une condition sur une seule ligne, en remplaçant le multiligne si ce qui rend le code compact.
[on_true] if [expression] else [on_false]
# 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
# 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
# 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 être écrite comme suit:
# 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
Plus un conseil qu'une réponse (vous n'avez pas besoin de répéter l'évidence pour la centaine de fois), mais je l'utilise parfois comme raccourci rapide 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 rythmique (même Ruby-ish :), mais personnellement, je trouve cela plus naturel - c’est-à-dire comment vous l’exprimeriez normalement, plus un peu plus attrayant visuellement dans de gros blocs de code.
Oui, vous pouvez l'utiliser de cette façon:
is_fat = True
state = "fat" if is_fat else "not fat"
En savoir plus sur opérateur conditionnel ternaire
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
a if condition else b
Mémorisez cette pyramide si vous avez du mal à vous souvenir:
condition
if else
a b
OUI, python a un opérateur ternaire, voici la syntaxe et un exemple de code pour démontrer la même chose :)
#[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")
Syntaxe: L'opérateur ternaire sera donné par:
[on_true] if [expression] else [on_false]
par exemple
x, y = 25, 50
big = x if x < y else y
print(big)
Oui.
>>> b = (True if 5 > 4 else False)
>>> print b
True
De nombreux langages de programmation dérivés de C
ont généralement la syntaxe suivante pour l'opérateur conditionnel ternaire:
<condition> ? <expression1> : <expression2>
Au début, la
Python
B enevolent D ictateur F ou L ife (je veux dire Guido van Rossum, bien sûr ) l'a rejeté (comme dans un style non Pythonic), car il est assez difficile à comprendre pour les personnes non habituées au langageC
. De plus, le signe deux-points:
a déjà de nombreuses utilisations dansPython
. Après l'approbation de PEP 308,Python
a finalement reçu sa propre expression conditionnelle de raccourci (ce que nous utilisons maintenant):
<expression1> if <condition> else <expression2>
Donc, premièrement, il évalue la condition. S'il renvoie True
, expression1 sera évalué pour donner le résultat, sinon expression2 sera évalué. En raison de la mécanique Lazy Evaluation _, 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 chaî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.
L'opérateur est "conditionnel". Ternary signifie simplement qu'il faut trois opérandes. Nous n'appelons pas + l'opérateur "binaire" +. Il n'y a aucune raison de continuer à le faire avec conditionnel. Que ce soit plus rapide ou plus compact que si-sinon est à côté du point. Ce qui compte, c’est que c’est une expression qui permet de l’intégrer à d’autres expressions. Correctement utilisé, il réduit la redondance et les opportunités de différences difficiles à identifier.
Une des alternatives à l'expression conditionnelle de Python est la suivante:
{True:"yes", False:"no"}[boolean]
qui a l'extension de Nice suivante:
{True:"yes", False:"no", None:"maybe"}[boolean_or_none]
La plus courte alternative reste:
("no", "yes")[boolean]
mais il n'y a pas d'alternative si vous voulez éviter l'évaluation de yes()
et de no()
dans ce qui suit:
yes() if [condition] else no()
Oui:
Supposons que vous vouliez donner à la variable x une valeur si un booléen est vrai et que
X = 5 si autre chose x = 10
X = [une valeur] if [si ceci est vrai, la première valeur est évaluée] else [une autre valeur est évaluée]
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)
va sortir
no Input
no Input
no Input
hello
['Hello']
True
Un moyen astucieux 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