Vraag Heeft Python een ternaire conditionele operator?


Als Python geen ternaire conditionele operator heeft, is het dan mogelijk om er een te simuleren met behulp van constructies met andere talen?


4427


oorsprong


antwoorden:


Ja dat klopt toegevoegd in versie 2.5.
De syntaxis is:

a if condition else b

Eerste condition wordt geëvalueerd en vervolgens een van beide a of b wordt geretourneerd op basis van de Boolean waarde van condition
Als condition evalueert naar waar  a is teruggekeerd, anders b wordt teruggestuurd.

Bijvoorbeeld:

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

Merk op dat conditionals een zijn uitdrukking, niet een uitspraak. Dit betekent dat je geen opdrachten of pass of andere verklaringen in een voorwaardelijke:

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

In een dergelijk geval moet u een normale gebruiken if verklaring in plaats van een voorwaardelijke.


Houd er rekening mee dat het door een aantal Pythonistas om verschillende redenen wordt afgekeurd:

  • De volgorde van de argumenten is anders dan veel andere talen (zoals C, Ruby, Java, etc.), wat kan leiden tot bugs wanneer mensen die onbekend zijn met het "verrassende" gedrag van Python het gebruiken (ze kunnen de volgorde omkeren).
  • Sommigen vinden het "onpraktisch", omdat het indruist tegen de normale gedachtestroom (eerst denken aan de conditie en dan aan de effecten).
  • Stilistische redenen.

Als je problemen hebt met het onthouden van de bestelling, onthoud dan dat als je het voorleest, je (bijna) zegt wat je bedoelt. Bijvoorbeeld, x = 4 if b > 8 else 9 wordt hardop voorgelezen als x will be 4 if b is greater than 8 otherwise 9.

Officiële documentatie:


5285



U kunt in een tuple indexeren:

(falseValue, trueValue)[test]

test moet terugkeren waar of vals.
Het is misschien veiliger om het altijd te implementeren als:

(falseValue, trueValue)[test == True]

of je kunt de ingebouwde gebruiken bool() verzekeren Boolean waarde:

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

591



Voor versies vóór 2,5 is er de truc:

[expression] and [on_true] or [on_false]

Het kan verkeerde resultaten geven wanneer on_true   heeft een onjuiste Booleaanse waarde.1
Hoewel het het voordeel heeft van het evalueren van uitdrukkingen van links naar rechts, wat naar mijn mening duidelijker is.

1. Is er een equivalent van C's "?:" Ternaire operator?


245



expression1 als staat anders expression2

>>> a = 1
>>> b = 2
>>> 1 if a > b else -1 
-1
>>> 1 if a > b else -1 if a < b else 0
-1

155



Van de documentatie:

Voorwaardelijke expressies (soms een "ternaire operator" genoemd) hebben de laagste prioriteit van alle Python-bewerkingen.

De uitdrukking x if C else y evalueert eerst de toestand, C (niet x); als C is waar, X wordt geëvalueerd en de waarde ervan wordt geretourneerd; anders, Y wordt geëvalueerd en de waarde ervan wordt geretourneerd.

Zien PEP 308 voor meer informatie over voorwaardelijke uitdrukkingen.

Nieuw sinds versie 2.5.


105



Een operator voor een voorwaardelijke uitdrukking in Python is in 2006 toegevoegd als onderdeel van Python Enhancement-voorstel 308. Zijn vorm verschilt van gebruikelijk ?: operator en het is:

<expression1> if <condition> else <expression2>

wat gelijk is aan:

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

Hier is een voorbeeld:

result = x if a > b else y

Een andere syntaxis die kan worden gebruikt (compatibel met versies vóór 2.5):

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

waar operanden zijn lui geëvalueerd.

Een andere manier is door een tuple te indexeren (wat niet consistent is met de conditionele operator van de meeste andere talen):

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

of expliciet geconstrueerd woordenboek:

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

Een andere (minder betrouwbare), maar eenvoudigere methode is om te gebruiken and en or operators:

result = (a > b) and x or y

dit zal echter niet werken als x zou zijn False.

Een mogelijke oplossing is om dit te doen x en y lijsten of tuples zoals in het volgende:

result = ((a > b) and [x] or [y])[0]

of:

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

Als u met woordenboeken werkt, kunt u in plaats van een ternaire voorwaarde gebruiken get(key, default), bijvoorbeeld:

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

Bron: ?: in Python op Wikipedia


78



@up:

Helaas, de

(falseValue, trueValue)[test]

oplossing heeft geen kortsluitingsgedrag; dus zowel falseValue als trueValue worden geëvalueerd ongeacht de conditie. Dit kan suboptimaal zijn of zelfs buggy (d.w.z. zowel trueValue als falseValue kunnen methoden zijn en bijwerkingen hebben).

Een oplossing hiervoor zou zijn

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

(uitvoering vertraagd totdat de winnaar bekend is;)), maar het introduceert inconsistentie tussen opvraagbare en niet-opvraagbare objecten. Bovendien lost het het geval niet op bij het gebruik van eigenschappen.

En zo gaat het verhaal - kiezen tussen 3 genoemde oplossingen is een wisselwerking tussen het hebben van de kortsluitingsfunctie, met gebruik van tenminste python 2.5 (IMHO geen probleem meer) en niet gevoelig zijn voor "trueValue-evalueert-naar-false" fouten.


72



Voor Python 2.5 en nieuwer is er een specifieke syntaxis:

[on_true] if [cond] else [on_false]

In oudere Pythons is een ternaire operator niet geïmplementeerd, maar het is mogelijk om deze te simuleren.

cond and on_true or on_false

Er is echter een potentieel probleem, dat als cond evalueert naar True en on_true evalueert naar False dan on_false wordt teruggestuurd in plaats van on_true. Als je dit gedrag wilt, is de methode OK, anders gebruik je dit:

{True: on_true, False: on_false}[cond is True] # is True, not == True

welke kan worden ingepakt door:

def q(cond, on_true, on_false)
    return {True: on_true, False: on_false}[cond is True]

en op deze manier gebruikt:

q(cond, on_true, on_false)

Het is compatibel met alle Python-versies.


48



Ternary-operator in verschillende programmeertalen

Hier probeer ik gewoon een belangrijk verschil te laten zien in ternary operator tussen een paar programmeertalen.

Ternary-operator in Javascript

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

Ternary-operator in Ruby

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

Ternary-operator in Scala

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

Ternaire-operator in R-programmering

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

Ternary-operator in Python

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

Nu kun je de schoonheid van de python-taal zien. het is zeer leesbaar en onderhoudbaar.


39