Question

Si Python ne dispose pas d'un opérateur conditionnel ternaire, est-il possible de simuler un à l'aide d'autres constructions de langage?

Était-ce utile?

La solution

Oui, il était ajouté dans la version 2.5. La syntaxe d'expression est:

a if condition else b

D'abord condition est évalué, alors exactement l'un des deux a ou b est évaluée et retournée sur la base valeur booléenne de condition. Si condition évalue à True, puis a est évalué et retourné, mais b est ignoré, ou bien lorsque b est évalué et retourné, mais a est ignoré.

Cela permet à un court-circuit parce que quand condition est vrai que a est évaluée et b n'est pas évalué du tout, mais quand condition est faux que b est évaluée et a n'est pas évalué du tout.

Par exemple:

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

Notez que conditionals sont une expression , pas une instruction . Cela signifie que vous ne pouvez pas utiliser des instructions d'affectation ou pass ou d'autres déclarations dans un conditionnel expression :

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

Vous pouvez toutefois utiliser des expressions conditionnelles pour assigner une variable comme ceci:

x = a if True else b

Pensez à l'expression conditionnelle que la commutation entre deux valeurs. Il est très utile lorsque vous êtes dans une « une valeur ou d'une autre » situation, mais ne fait pas beaucoup d'autre.

Si vous devez utiliser des instructions, vous devez utiliser un if normale Déclaration au lieu d'un conditionnel expression .


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

  • L'ordre des arguments est différent de ceux de l'opérateur ternaire condition ? a : b classique de nombreuses autres langues (comme C, C ++, Go, Perl, Ruby, Java, Javascript, etc.), ce qui peut conduire à des bugs quand les gens peu familiers avec le comportement « surprenant » de Python utiliser (ils peuvent inverser l'ordre des arguments).
  • Certains le trouvent « trop compliqué », car il est contraire à l'écoulement normal de la pensée (la pensée de la condition d'abord, puis les effets).
  • raisons Stylistic. (Bien que la 'ligne if' peut être vraiment utile et rendre votre script plus concis, il fait vraiment compliquer votre code)

Si vous éprouvez des difficultés à se souvenir de l'ordre, alors se rappeler que lors de la lecture à haute voix, vous (presque) dire 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:

Autres conseils

Vous pouvez indexer dans un tuple:

(falseValue, trueValue)[test]

test doit revenir True ou false .
Il pourrait être plus sûr de mettre en œuvre toujours comme:

(falseValue, trueValue)[test == True]

ou vous pouvez utiliser le haut- bool() pour assurer une la valeur booléenne:

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

<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

De la documentation :

  

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

     

Le x if C else y d'expression évalue d'abord l'état, C ( pas x ); si C est vrai, x est évaluée et sa valeur est retournée; autrement, y est évaluée 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 de ?: commun et il est:

<expression1> if <condition> else <expression2>

qui est équivalent à:

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

Voici un exemple:

result = x if a > b else y

Une autre syntaxe qui peut être utilisé (compatible avec les versions antérieures à 2,5):

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

où opérandes sont évalué paresseusement .

Une autre façon est par l'indexation d'un tuple (qui ne correspond pas à l'opérateur conditionnel de la plupart des autres langues):

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

ou dictionnaire construit explicitement:

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

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

result = (a > b) and x or y

mais cela ne fonctionnera pas si x serait False.

Une solution possible est de faire des listes de x et y ou tuples comme dans ce qui 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 de get(key, default) , par exemple:

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

Source: : en Python sur Wikipedia

Malheureusement, le

(falseValue, trueValue)[test]

solution n'a pas le comportement de court-circuit; donc à la fois falseValue et trueValue sont évaluées indépendamment de la condition. Cela pourrait être suboptimale ou même poussette (dire à la fois trueValue et falseValue pourraient être des méthodes et des effets secondaires).

Une solution à ce serait

(lambda: falseValue, lambda: trueValue)[test]()
(Exécution retardée jusqu'à ce que le gagnant est connu;)

), mais il présente l'incohérence entre les objets appelables et non remboursables par anticipation. De plus, il ne résout pas le cas lors de l'utilisation des propriétés.

Et l'histoire va - choisir entre 3 solutions mentionnées est un compromis entre avoir la fonction de court-circuit, en utilisant Зython 2,5 au moins (à mon humble avis pas plus un problème) et ne pas être enclin à « trueValue Évalue à erreurs -false ».

ternaires opérateur dans différents langages de programmation

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

  

ternaires opérateur en Javascript

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

ternaires opérateur en Ruby

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

opérateur ternaires Scala

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

opérateur dans la programmation ternaires R

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

opérateur ternaires en Python

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

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

[on_true] if [cond] else [on_false]

Dans les anciennes Pythons un opérateur ternaire n'est pas mis en œuvre, mais il est possible de simuler.

cond and on_true or on_false

Bien, il y a un problème potentiel qui, si elle cond évalue à True et on_true évalue à False alors on_false est retourné au lieu de on_true. Si vous voulez que 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.

Vous pourriez trouver

cond and on_true or on_false

mais cela a conduit à 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ù que vous attendez pour un opérateur ternaire normale 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 conditionnel ternaire?

Oui. A partir du :

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

La partie intéressante 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 (qui est, évaluée que si expression2 est faux dans un contexte booléen). Et à cause de la définition récursive, vous pouvez les enchaîner indéfiniment (même si elle peut considérer 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 d'un else. Les gens d'apprentissage de la liste et compréhensions expressions du générateur peuvent trouver que cela soit une leçon difficile à apprendre - ce qui suit ne fonctionnera pas, comme Python attend une troisième expression d'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 une pièce incomplète de la logique (peut-être l'utilisateur attend un non-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 conditionnel ternaire.

syntaxe alternative pour un cas plus étroit:

Vous pouvez trouver un peu pénible à é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 si elle est simplement une variable locale. Cependant, un langage commun et Pythonic pour cette utilisation performante cas est d'utiliser le comportement de court-circuiter or:

expression1 or expression2

qui est équivalent à la sémantique. Notez que certains guides de style peuvent limiter cet usage pour des raisons de clarté -. Il n'emballer beaucoup de sens en très peu de syntaxe

Simuler 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'

vous pouvez le faire: -

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

Exemple: -

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

imprimera « bizarre » si le nombre est impair ou « même » si le nombre est encore.


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

Remarque: - 0, Aucun, Faux, emptylist, emptyString évaluée comme fausse. Et toutes les données autres que 0 est évaluée à True.

Voilà comment cela fonctionne:

si la condition [condition] devient "vrai" alors, expression_1 sera évalué mais pas expression_2. Si nous « et » quelque chose avec 0 (zéro), le résultat sera toujours être Fasle .Donc dans la déclaration ci-dessous,

0 and exp

L'expression exp ne sera pas évaluée du tout depuis « et » avec 0 sera toujours à zéro et évaluer il n'y a pas besoin d'évaluer l'expression. Voici comment le compilateur fonctionne lui-même, dans toutes les langues.

Dans

1 or exp

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

Mais dans le cas de

True and exp1 or exp2

La deuxième expression exp2 ne sera pas évaluée car True and exp1 serait vrai si exp1 est pas faux.

De même, dans

False and exp1 or exp2

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


Remarque: - Ce type de ramification à l'aide « ou » et « et » ne peut être utilisé lorsque le expression_1 n'a pas une valeur de vérité Faux (ou 0 ou Aucun ou emptylist [] ou emptystring « ».) car si expression_1 devient False, la expression_2 sera évaluée en raison de la présence « ou » entre exp_1 et exp_2.

Si vous voulez continuer à le faire fonctionner pour tous les cas, indépendamment de ce que exp_1 et les valeurs de vérité sont exp_2, faites ceci: -

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

ternaires opérateur conditionnel permet simplement de tester une condition dans une seule ligne remplaçant le multiligne if-else faire le pacte de code.

Syntaxe:

  

[on_true] si [expression] autre [on_false]

1- Méthode simple à 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'utiliser tuples, 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 ternaires peut être écrit comme imbriquée 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")

Au-dessus de l'approche 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

Plus d'une pointe à une réponse (ne pas besoin de répéter l'évidence pour le temps de hundreth), mais je l'utilise parfois comme un raccourci oneliner dans ces constructions:

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

, devient:

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

Certains (beaucoup :) peuvent désapprouver comme unpythonic (même, :) rubis-ish, mais je trouve personnellement plus naturel - à savoir comment vous exprimer normalement, plus un peu plus attrayant visuellement dans les grands blocs de code.

a if condition else b

Il suffit de mémoriser cette pyramide si vous avez du mal à se rappeler:

     condition
  if           else
a                   b 

OUI, python a un opérateur ternaire, voici la syntaxe et un code d'exemple pour démontrer la même:)

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

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

<condition> ? <expression1> : <expression2>
  

Dans un premier temps, le Python B enevolent D ictator F ou L ife (I signifie Guido van Rossum , bien sûr) rejeté (comme le style non Pythonic), car il est assez difficile à comprendre pour les gens pas habitués à C langue. En outre, le signe du côlon : a déjà de nombreuses utilisations dans Python. Après PEP 308 a été approuvé, Python a finalement reçu son propre raccourci expression conditionnelle (ce que nous utilisons maintenant):

<expression1> if <condition> else <expression2>

Alors, tout d'abord, il évalue l'état. Si elle retourne True, expression1 seront évaluées pour donner le résultat, sinon expression2 seront évaluées. En raison de Évaluation Lazy - la mécanique. Une seule expression sera exécutée

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

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

# Result is 'High'

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'

La suivante est identique à une précédente:

pressure = 5

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

# Result is 'Normal'

Hope this helps.

L'une des alternatives à la expression conditionnelle est le suivant:

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

qui a l'extension bien suivant:

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

Le plus court altérant reste:

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

mais il n'y a pas d'alternative si vous voulez éviter l'évaluation des deux yes() et no() dans ce qui suit:

yes() if [condition] else no()

si la variable est définie et que vous voulez vérifier si elle a de la 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

Une belle façon de chaîne 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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top