Als Python geen ternaire voorwaardelijke operator heeft, is het dan mogelijk om er een te simuleren met behulp van andere taalconstructies?
Antwoord 1, autoriteit 100%
Ja, het was toegevoegd in versie 2.5. De syntaxis van de uitdrukking is:
a if condition else b
Eerste condition
wordt geëvalueerd, daarna wordt precies één van a
of b
geëvalueerd en geretourneerd op basis van de Boolean waarde van condition
. Als condition
resulteert in True
, dan wordt a
geëvalueerd en geretourneerd, maar wordt b
genegeerd, of anders wanneer b
wordt geëvalueerd en geretourneerd, maar a
wordt genegeerd.
Dit maakt kortsluiting mogelijk omdat wanneer condition
waar is, alleen a
wordt geëvalueerd en b
helemaal niet wordt geëvalueerd, maar wanneer condition
is onwaar alleen b
wordt geëvalueerd en a
wordt helemaal niet geëvalueerd.
Bijvoorbeeld:
>>> 'true' if True else 'false'
'true'
>>> 'true' if False else 'false'
'false'
Houd er rekening mee dat conditionals een uitdrukking zijn, geen instructie. Dit betekent dat je geen toewijzingsinstructies of pass
of andere statements kunt gebruiken binnen een voorwaardelijke expressie:
>>> pass if False else x = 3
File "<stdin>", line 1
pass if False else x = 3
^
SyntaxError: invalid syntax
U kunt echter voorwaardelijke expressies gebruiken om een variabele als volgt toe te wijzen:
x = a if True else b
Zie de voorwaardelijke expressie als schakelen tussen twee waarden. Het is erg handig wanneer u zich in een situatie van ‘een of andere waarde’ bevindt, maar het doet niet veel anders.
Als je statements moet gebruiken, moet je een normale if
statement gebruiken in plaats van een voorwaardelijke expressie.
Houd er rekening mee dat sommige Pythonista’s om verschillende redenen de wenkbrauwen fronsen:
- De volgorde van de argumenten is anders dan die van de klassieke
condition ? a : b
ternaire operator uit vele andere talen (zoals C, C++, Go, Perl, Ruby, Java, Javascript, enz.), wat kan leiden tot bugs wanneer mensen niet bekend zijn met Python’s "surprising" gedrag gebruiken (ze kunnen de volgorde van het argument omkeren). - Sommigen vinden het “onhandig”, omdat het indruist tegen de normale gedachtegang (eerst aan de toestand denken en dan aan de effecten).
- Stilistische redenen. (Hoewel de ‘inline
if
‘ echt nuttig kan zijn en je script beknopter kan maken, maakt het je code echt ingewikkelder)
Als je moeite hebt om de volgorde te onthouden, onthoud dan dat wanneer je hardop voorleest, je (bijna) zegt wat je bedoelt. Bijvoorbeeld, x = 4 if b > 8 else 9
hardop voorgelezen omdat x will be 4 if b is greater than 8 otherwise 9
.
Officiële documentatie:
Antwoord 2, autoriteit 11%
U kunt indexeren in een tuple:
(falseValue, trueValue)[test]
test
moet True of False retourneren.
Het is misschien veiliger om het altijd te implementeren als:
(falseValue, trueValue)[test == True]
of u kunt de ingebouwde bool()
om een Boolean waarde:
(falseValue, trueValue)[bool(<expression>)]
Antwoord 3, autoriteit 5%
Voor versies ouder dan 2.5 is er de truc:
[expression] and [on_true] or [on_false]
Het kan verkeerde resultaten geven wanneer on_true
heeft een valse booleaanse waarde.1
Hoewel het het voordeel heeft dat uitdrukkingen van links naar rechts worden geëvalueerd, wat naar mijn mening duidelijker is.
1. Is er een equivalent van C s ?: ternaire operator?
Antwoord 4, autoriteit 4%
<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
Antwoord 5, autoriteit 2%
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 voorwaarde, C (niet x); als C waar is, wordt x geëvalueerd en wordt de waarde ervan geretourneerd; anders wordt y geëvalueerd en wordt de waarde geretourneerd.Zie PEP 308 voor meer details over voorwaardelijke expressies.
Nieuw sinds versie 2.5.
Antwoord 6, autoriteit 2%
Een operator voor een voorwaardelijke expressie in Python is in 2006 toegevoegd als onderdeel van Python Enhancement Voorstel 308. De vorm verschilt van de gewone ?:
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 lui worden geëvalueerd.
Een andere manier is door een tuple te indexeren (wat niet consistent is met de voorwaardelijke operator van de meeste andere talen):
result = (y, x)[a > b]
of expliciet samengesteld woordenboek:
result = {True: x, False: y}[a > b]
Een andere (minder betrouwbare), maar eenvoudigere methode is om de operators and
en or
te gebruiken:
result = (a > b) and x or y
dit werkt echter niet als x
False
zou zijn.
Een mogelijke oplossing is om x
en y
lijsten of tupels te maken zoals hieronder:
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 te gebruiken, profiteren van get(key, default)
, bijvoorbeeld:
shell = os.environ.get('SHELL', "/bin/sh")
Bron: ?: in Python op Wikipedia
Antwoord 7
Helaas is de
(falseValue, trueValue)[test]
oplossing heeft geen kortsluitgedrag; dus zowel falseValue
als trueValue
worden geëvalueerd ongeacht de voorwaarde. Dit kan suboptimaal zijn of zelfs fouten bevatten (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 oproepbare en niet-oproepbare objecten. Bovendien lost het het geval bij het gebruik van eigenschappen niet op.
En zo gaat het verhaal – kiezen tussen 3 genoemde oplossingen is een afweging tussen het hebben van de kortsluitfunctie, het gebruik van ten minste ython 2.5 (IMHO geen probleem meer) en niet vatbaar zijn voor “trueValue
-evaluates-to-false” fouten.
Antwoord 8
Ternaire operator in verschillende programmeertalen
Hier probeer ik een belangrijk verschil in ternary operator
tussen een aantal programmeertalen te laten zien.
Ternaire operator in Javascript
var a = true ? 1 : 0;
# 1
var b = false ? 1 : 0;
# 0
Ternaire operator in Ruby
a = true ? 1 : 0
# 1
b = false ? 1 : 0
# 0
Ternaire 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
Ternaire operator in Python
a = 1 if True else 0
# 1
b = 1 if False else 0
# 0
Antwoord 9
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 tot True
en on_true
evalueert tot False
dan wordt on_false
geretourneerd in plaats van on_true
. Als je dit gedrag wilt, is de methode OK, gebruik anders dit:
{True: on_true, False: on_false}[cond is True] # is True, not == True
die 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.
Antwoord 10
Misschien vind je
cond and on_true or on_false
maar dit leidde tot problemen wanneer on_true == 0
>>> x = 0
>>> print x == 0 and 0 or 1
1
>>> x = 1
>>> print x == 0 and 0 or 1
1
waar je dit resultaat zou verwachten voor een normale ternaire operator
>>> x = 0
>>> print 0 if x == 0 else 1
0
>>> x = 1
>>> print 0 if x == 0 else 1
1
Antwoord 11
Heeft Python een ternaire voorwaardelijke operator?
Ja. Uit het grammaticabestand:
test: or_test ['if' or_test 'else' test] | lambdef
Het interessante deel is:
or_test ['if' or_test 'else' test]
Dus een ternaire voorwaardelijke bewerking heeft de vorm:
expression1 if expression2 else expression3
expression3
wordt lui geëvalueerd (dat wil zeggen, alleen geëvalueerd als expression2
onwaar is in een booleaanse context). En vanwege de recursieve definitie kun je ze voor onbepaalde tijd aaneenketenen (hoewel dit als een slechte stijl kan worden beschouwd.)
expression1 if expression2 else expression3 if expression4 else expression5 # and so on
Een opmerking over het gebruik:
Houd er rekening mee dat elke if
moet worden gevolgd door een else
. Mensen die lijstbegrippen en generatorexpressies leren, kunnen dit een moeilijke les vinden om te leren – het volgende zal niet werken, omdat Python een derde expressie verwacht voor een else:
[expression1 if expression2 for element in iterable]
# ^-- need an else here
die een SyntaxError: invalid syntax
oplevert.
Dus het bovenstaande is ofwel een onvolledig stuk logica (misschien verwacht de gebruiker een no-op in de false-conditie) of wat de bedoeling kan zijn is om expression2 als filter te gebruiken – merkt op dat het volgende legale Python is:
[expression1 for element in iterable if expression2]
expression2
werkt als een filter voor het begrip van de lijst en is geen een ternaire voorwaardelijke operator.
Alternatieve syntaxis voor een nauwer geval:
Misschien vind je het wat pijnlijk om het volgende te schrijven:
expression1 if expression1 else expression2
expression1
moet twee keer worden geëvalueerd met het bovenstaande gebruik. Het kan redundantie beperken als het gewoon een lokale variabele is. Een algemeen en goed presterend Python-idioom voor deze use-case is echter om het snelkoppelingsgedrag van or
te gebruiken:
expression1 or expression2
wat equivalent is in semantiek. Merk op dat sommige stijlgidsen dit gebruik kunnen beperken vanwege de duidelijkheid – het bevat veel betekenis in zeer weinig syntaxis.
Antwoord 12
De ternaire operator van Python simuleren.
Bijvoorbeeld
a, b, x, y = 1, 2, 'a greather than b', 'b greater than a'
result = (lambda:y, lambda:x)[a > b]()
uitvoer:
'b greater than a'
Antwoord 13
a if condition else b
Onthoud deze piramide gewoon als je moeite hebt met onthouden:
condition
if else
a b
Antwoord 14
Een van de alternatieven voor Python’s voorwaardelijke expressie
"yes" if boolean else "no"
is het volgende:
{True:"yes", False:"no"}[boolean]
die de volgende mooie extensie heeft:
{True:"yes", False:"no", None:"maybe"}[boolean_or_none]
Het kortste alternatief blijft:
("no", "yes")[boolean]
maar er is geen alternatief voor
yes() if boolean else no()
als u de evaluatie van yes()
en no()
wilt vermijden, omdat in
(no(), yes())[boolean] # bad
zowel no()
als yes()
worden geëvalueerd.
Antwoord 15
Met de ternaire voorwaardelijke operator kan een voorwaarde eenvoudig op een enkele regel worden getest, waarbij de multiregel als-anders wordt vervangen, waardoor de code compact wordt.
Syntaxis:
[on_true] if [expression] else [on_false]
1- Eenvoudige methode om ternaire operator te gebruiken:
# 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- Directe methode voor het gebruik van tuples, Dictionary en 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- De ternaire operator kan worden geschreven als geneste 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")
Bovenstaande benadering kan worden geschreven als:
# 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
Antwoord 16
u kunt dit doen:-
[condition] and [expression_1] or [expression_2] ;
Voorbeeld:-
print(number%2 and "odd" or "even")
Dit zou “vreemd” afdrukken als het getal oneven of “even” is als het getal even is.
Het resultaat:- Als de voorwaarde waar is, wordt exp_1 uitgevoerd, anders wordt exp_2 uitgevoerd.
Opmerking:- 0 , None , False , emptylist , emptyString evalueert als False.
En alle andere gegevens dan 0 worden geëvalueerd als True.
Zo werkt het:
als de voorwaarde [voorwaarde] “True” wordt dan wordt expression_1 geëvalueerd maar niet expression_2 .
Als we "en" iets met 0 (nul), het resultaat zal altijd fale zijn. Dus in de onderstaande verklaring,
0 and exp
De uitdrukking exp wordt helemaal niet geëvalueerd sinds "and" met 0 evalueert altijd tot nul en het is niet nodig om de uitdrukking te evalueren. Dit is hoe de compiler zelf werkt, in alle talen.
In
1 or exp
de uitdrukking exp wordt helemaal niet geëvalueerd sinds "of" met 1 zal altijd 1 zijn. Dus het zal niet de moeite nemen om de uitdrukking exp te evalueren, aangezien het resultaat sowieso 1 zal zijn. (optimalisatiemethoden voor compilers).
Maar in het geval van
True and exp1 or exp2
De tweede expressie exp2 wordt niet geëvalueerd omdat True and exp1
True zijn als exp1 niet false is.
Zo ook in
False and exp1 or exp2
De uitdrukking exp1 wordt niet geëvalueerd omdat False gelijk is aan het schrijven van 0 en het doen van "en" met 0 zou zelf 0 zijn, maar na exp1 sinds "of" wordt gebruikt, zal het de uitdrukking exp2 evalueren na "of" .
Opmerking:- Dit soort vertakkingen met behulp van "of" en "en" kan alleen worden gebruikt als expressie_1 geen Waarheidswaarde False heeft (of 0 of Geen of lege lijst [ ] of lege tekenreeks ‘ ‘.) aangezien als expressie_1 False wordt, dan wordt expressie_2 geëvalueerd vanwege de aanwezigheid "of" ; tussen exp_1 en exp_2.
Als je het toch voor alle gevallen wilt laten werken, ongeacht wat de waarheidswaarden van exp_1 en exp_2 zijn, doe dit:-
[condition] and ([expression_1] or 1) or [expression_2] ;
Antwoord 17
Meer een tip dan een antwoord (hoef het voor de hand liggende niet voor de honderdste keer te herhalen), maar ik gebruik het soms als een oneliner-snelkoppeling in dergelijke constructies:
if conditionX:
print('yes')
else:
print('nah')
, wordt:
print('yes') if conditionX else print('nah')
Sommigen (velen 🙂 zien het misschien als onpythonisch (zelfs, robijnachtig :)), maar persoonlijk vind ik het natuurlijker – dat wil zeggen hoe je het normaal zou uitdrukken, plus een beetje meer visueel aantrekkelijk in grote blokken met code.
Antwoord 18
Zoals reeds beantwoord, ja, er is een ternaire operator in python:
<expression 1> if <condition> else <expression 2>
Aanvullende informatie:
Als <expression 1>
de voorwaarde is die u kunt gebruiken Kort -cirquit evaluatie:
a = True
b = False
# Instead of this:
x = a if a else b
# You could use Short-cirquit evaluation:
x = a or b
PS: Een Short-Cirquit-evaluatie is natuurlijk geen ternaire operator, maar vaak wordt de ternaire gebruikt in gevallen waar de kortsluiting voldoende zou zijn.
Antwoord 19
Het antwoord van Vinko Vrsalovic is goed genoeg. Er is nog één ding:
Houd er rekening mee dat conditionals een uitdrukking zijn, geen instructie. Dit betekent dat u geen toewijzingsinstructies of
pass
of andere statements kunt gebruiken binnen een voorwaardelijke expressie
Walrus-operator in Python 3.8
Nadat de walrus-operator werd geïntroduceerd in Python 3.8, is er iets veranderd.
(a := 3) if True else (b := 5)
geeft a = 3
en b is not defined
,
(a := 3) if False else (b := 5)
geeft a is not defined
en b = 5
, en
c = (a := 3) if False else (b := 5)
geeft c = 5
, a is not defined
en b = 5
.
Zelfs als dit lelijk is, kunnen toewijzingen worden gedaan binnen voorwaardelijke expressies na Python 3.8. Hoe dan ook, het is in dit geval nog steeds beter om de normale if
instructie te gebruiken.
Antwoord 20
Veel programmeertalen die zijn afgeleid van C
hebben meestal de volgende syntaxis van een ternaire voorwaardelijke operator:
<condition> ? <expression1> : <expression2>
In eerste instantie de
Python
Benevolente Dictator Fof L ife (ik bedoel natuurlijk Guido van Rossum) verwierp het (als niet-pythonische stijl), omdat het vrij moeilijk te begrijpen is voor mensen die niet gewend zijn aanC
-taal. Ook het dubbele punt:
wordt al veel gebruikt inPython
. Nadat PEP 308 was goedgekeurd, ontvingPython
eindelijk zijn eigen voorwaardelijke snelkoppeling (wat we nu gebruiken):
<expression1> if <condition> else <expression2>
Dus, ten eerste evalueert het de conditie. Als het True
retourneert, wordt expression1 geëvalueerd om het resultaat te geven, anders wordt expression2 geëvalueerd. Vanwege de Lazy Evaluation-mechanica wordt er slechts één expressie uitgevoerd.
Hier zijn enkele voorbeelden (voorwaarden worden van links naar rechts geëvalueerd):
pressure = 10
print('High' if pressure < 20 else 'Critical')
# Result is 'High'
Ternaire operatoren kunnen in serie worden geschakeld:
pressure = 5
print('Normal' if pressure < 10 else 'High' if pressure < 20 else 'Critical')
# Result is 'Normal'
De volgende is hetzelfde als de vorige:
pressure = 5
if pressure < 20:
if pressure < 10:
print('Normal')
else:
print('High')
else:
print('Critical')
# Result is 'Normal'
Hopelijk helpt dit.
Antwoord 21
JA, python heeft een ternaire operator, hier is de syntaxis en een voorbeeldcode om hetzelfde te demonstreren 🙂
#[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")
Antwoord 22
Andere antwoorden spreken correct over de ternaire operator van Python. Ik zou dit willen aanvullen door een scenario te noemen waarvoor vaak de ternaire operator wordt gebruikt, maar waarvoor een beter idioom bestaat. Dit is het scenario van het gebruik van een standaardwaarde.
Stel dat we option_value
willen gebruiken met een standaardwaarde als deze niet is ingesteld:
run_algorithm(option_value if option_value is not None else 10)
of, als option_value
nooit is ingesteld op een valse waarde (0
, ""
, enz.), gewoon
run_algorithm(option_value if option_value else 10)
In dit geval is echter een steeds betere oplossing om gewoon te schrijven
run_algorithm(option_value or 10)
Antwoord 23
Python heeft een ternaire vorm voor opdrachten; er kan echter zelfs een kortere vorm zijn waarvan mensen op de hoogte moeten zijn.
Het is heel gebruikelijk om aan een variabele een of andere waarde toe te wijzen, afhankelijk van een voorwaarde.
>>> li1 = None
>>> li2 = [1, 2, 3]
>>>
>>> if li1:
... a = li1
... else:
... a = li2
...
>>> a
[1, 2, 3]
^ Dit is het lange formulier om zulke opdrachten te maken.
Hieronder staat de ternaire vorm. Maar dit is niet de meest beknopte manier – zie laatste voorbeeld.
>>> a = li1 if li1 else li2
>>>
>>> a
[1, 2, 3]
>>>
Met Python kun je eenvoudig or
gebruiken voor alternatieve opdrachten.
>>> a = li1 or li2
>>>
>>> a
[1, 2, 3]
>>>
Het bovenstaande werkt omdat li1
None
is en de interp behandelt dat als False in logische expressies. De interp gaat dan verder en evalueert de tweede uitdrukking, die niet None
is en het is geen lege lijst – dus wordt deze toegewezen aan a.
Dit werkt ook met lege lijsten. Als u bijvoorbeeld a
wilt toewijzen aan een lijst met items.
>>> li1 = []
>>> li2 = [1, 2, 3]
>>>
>>> a = li1 or li2
>>>
>>> a
[1, 2, 3]
>>>
Als je dit weet, kun je dergelijke opdrachten eenvoudig uitvoeren wanneer je ze tegenkomt. Dit werkt ook met strings en andere iterables. Je zou een a
kunnen toewijzen welke string niet leeg is.
>>> s1 = ''
>>> s2 = 'hello world'
>>>
>>> a = s1 or s2
>>>
>>> a
'hello world'
>>>
Ik vond de C ternaire syntaxis altijd leuk, maar Python gaat nog een stap verder!
Ik begrijp dat sommigen zeggen dat dit geen goede stilistische keuze is omdat het afhankelijk is van mechanica die niet meteen voor alle ontwikkelaars duidelijk is. Ik ben het persoonlijk niet eens met dat standpunt. Python is een syntaxisrijke taal met veel idiomatische trucs die niet meteen duidelijk zijn voor de liefhebber. Maar hoe meer je de mechanica van het onderliggende systeem leert en begrijpt, hoe meer je het op prijs stelt.
Antwoord 24
Een handige manier om meerdere operators aan elkaar te koppelen:
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
Antwoord 25
Ik vind de standaard python-syntaxis val = a if cond else b
omslachtig, dus soms doe ik dit:
iif = lambda (cond, a, b): a if cond else b
# so I can then use it like:
val = iif(cond, a, b)
Natuurlijk heeft het het nadeel dat het altijd beide kanten (a en b) evalueert, maar de syntaxis is veel duidelijker voor mij
Antwoord 26
Als variabele is gedefinieerd en u wilt controleren of deze een waarde heeft, kunt u gewoon 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)
zal uitvoeren
no Input
no Input
no Input
hello
['Hello']
True
Antwoord 27
is_spacial=True if gender = "Female" else (True if age >= 65 else False)
**
het kan naar behoefte worden genest. veel succes
**