Wenn Python keinen ternären bedingten Operator hat, ist es möglich, einen mit anderen Sprachkonstrukten zu simulieren?
6045
Wenn Python keinen ternären bedingten Operator hat, ist es möglich, einen mit anderen Sprachkonstrukten zu simulieren?
case [...] { when ... then ...} [ else ... ] end
einen ähnlichen Effekt, ist aber überhaupt nicht ternär.Antworten:
Ja, es wurde in Version 2.5 hinzugefügt . Die Ausdruckssyntax lautet:
Zuerst
condition
wird ausgewertet, dann genau einer von beidena
oderb
wird ausgewertet und basierend auf dem Booleschen Wert von zurückgegebencondition
. Wenncondition
ausgewertet wirdTrue
,a
wird ausgewertet und zurückgegeben, aberb
ignoriert, oder wennb
ausgewertet und zurückgegeben, abera
ignoriert wird.Dies ermöglicht einen Kurzschluss, da nur wenn
condition
wahr wahra
ist, ausgewertet wird und überhauptb
nicht ausgewertet wird, wenncondition
jedoch falsch ist, nurb
ausgewertet wird und überhaupta
nicht ausgewertet wird.Zum Beispiel:
Beachten Sie, dass Bedingungen ein Ausdruck und keine Anweisung sind . Dies bedeutet, dass Sie keine Zuweisungsanweisungen
pass
oder andere Anweisungen innerhalb eines bedingten Ausdrucks verwenden können :Sie können jedoch bedingte Ausdrücke verwenden, um eine Variable wie folgt zuzuweisen:
Stellen Sie sich den bedingten Ausdruck als Umschalten zwischen zwei Werten vor. Es ist sehr nützlich, wenn Sie sich in einer Situation mit dem einen oder anderen Wert befinden, aber sonst macht es nicht viel.
Wenn Sie Anweisungen verwenden müssen, müssen Sie eine normale
if
Anweisung anstelle eines bedingten Ausdrucks verwenden .Denken Sie daran, dass es von einigen Pythonisten aus mehreren Gründen missbilligt wird:
condition ? a : b
ternären Operators aus vielen anderen Sprachen (wie C, C ++, Go, Perl, Ruby, Java, Javascript usw.), was zu Fehlern führen kann, wenn Personen mit Pythons nicht vertraut sind. " überraschendes "Verhalten verwenden es (sie können die Argumentreihenfolge umkehren).if
' sehr nützlich sein und Ihr Skript präziser gestalten kann, kompliziert es Ihren Code wirklich)Wenn Sie Probleme haben, sich an die Bestellung zu erinnern, denken Sie daran, dass Sie beim Vorlesen (fast) sagen, was Sie meinen. Zum Beispiel
x = 4 if b > 8 else 9
wird vorgelesen alsx will be 4 if b is greater than 8 otherwise 9
.Offizielle Dokumentation:
quelle
f(x) = |x| = x if x > 0 else -x
klingt jedoch für Mathematiker sehr natürlich. Sie können es in den meisten Fällen auch als A verstehen, außer wenn C, dann sollten Sie stattdessen B tun ...z = 3 + x if x < y else y
. Wennx=2
undy=1
, könnten Sie erwarten, dass dies 4 ergibt, aber es würde tatsächlich 1 ergeben. Diesz = 3 + (x if x > y else y)
ist die richtige Verwendung.z = 3 + x if x < y else 3 + y
) oder die Bedingung (z = 3 + (x if x < y else y)
oderz = (x if x < y else y) + 3
)Sie können in ein Tupel indizieren:
test
muss True oder False zurückgeben .Es könnte sicherer sein, es immer wie folgt zu implementieren:
oder Sie können die integrierte Funktion verwenden
bool()
, um einen Booleschen Wert sicherzustellen :quelle
(lambda: print("a"), lambda: print("b"))[test==true]()
[]
s befindet, ein beliebiger Ausdruck sein kann. Aus Sicherheitsgründen können Sie die Wahrhaftigkeit auch explizit schriftlich prüfen[bool(<expression>)]
. Diebool()
Funktion gibt es seit v2.2.1.True
undFalse
als Schlüssel indiziert habe :{True:trueValue, False:falseValue}[test]
Ich weiß nicht, ob dies weniger effizient ist, aber es vermeidet zumindest das Ganze "elegante" vs. "hässliche" Debatte. Es gibt keine Unklarheit, dass Sie es eher mit einem Booleschen als mit einem Int zu tun haben.Für Versionen vor 2.5 gibt es den Trick:
Es kann zu falschen Ergebnissen führen, wenn
on_true
ein falscher Boolescher Wert vorliegt. 1Obwohl es den Vorteil hat, Ausdrücke von links nach rechts zu bewerten, ist dies meiner Meinung nach klarer.
1. Gibt es ein Äquivalent zu Cs ternärem Operator?
quelle
<expression 1> if <condition> else <expression 2>
quelle
Aus der Dokumentation :
Neu seit Version 2.5.
quelle
Ein Operator für einen bedingten Ausdruck in Python wurde 2006 als Teil von Python Enhancement Proposal 308 hinzugefügt . Seine Form unterscheidet sich vom üblichen
?:
Operator und es ist:was äquivalent ist zu:
Hier ist ein Beispiel:
Eine andere Syntax, die verwendet werden kann (kompatibel mit Versionen vor 2.5):
wo Operanden träge ausgewertet werden .
Eine andere Möglichkeit besteht darin, ein Tupel zu indizieren (was nicht mit dem bedingten Operator der meisten anderen Sprachen übereinstimmt):
oder explizit erstelltes Wörterbuch:
Eine andere (weniger zuverlässige), aber einfachere Methode ist die Verwendung
and
und dieor
Bedienung:Dies wird jedoch nicht funktionieren, wenn
x
dies der Fall wäreFalse
.Eine mögliche Problemumgehung besteht darin,
x
wie folgt zu erstellen undy
aufzulisten oder zu tupeln:oder:
Wenn Sie mit Wörterbüchern arbeiten, anstatt eine ternäre Bedingung zu verwenden, können Sie beispielsweise Folgendes nutzen
get(key, default)
:Quelle: ?: In Python bei Wikipedia
quelle
result = {1: x, 0: y}[a > b]
ist eine andere mögliche Variante (True
undFalse
sind tatsächlich ganze Zahlen mit Werten1
und0
)Leider ist die
Lösung hat kein Kurzschlussverhalten; somit werden beide
falseValue
undtrueValue
unabhängig von der Bedingung ausgewertet. Dies kann suboptimal oder sogar fehlerhaft sein (dh beidestrueValue
undfalseValue
kann Methoden sein und Nebenwirkungen haben).Eine Lösung hierfür wäre
(Ausführung verzögert, bis der Gewinner bekannt ist;)), führt jedoch zu Inkonsistenzen zwischen aufrufbaren und nicht aufrufbaren Objekten. Außerdem wird der Fall bei Verwendung von Eigenschaften nicht gelöst.
Und so geht die Geschichte weiter: Die Wahl zwischen drei genannten Lösungen ist ein Kompromiss zwischen der Kurzschlussfunktion, der Verwendung von mindestens 2.5ython 2.5 (meiner Meinung nach kein Problem mehr) und der
trueValue
Nichtanfälligkeit für " -evaluates-to-false" -Fehler .quelle
if else if
.Ternärer Operator in verschiedenen Programmiersprachen
Hier versuche ich nur, einen wichtigen Unterschied
ternary operator
zwischen einigen Programmiersprachen aufzuzeigen.quelle
Für Python 2.5 und höher gibt es eine bestimmte Syntax:
In älteren Pythons ist ein ternärer Operator nicht implementiert, aber es ist möglich, ihn zu simulieren.
Obwohl, es ist ein potenzielles Problem, das wenn
cond
auswertet zuTrue
undon_true
auswertet , umFalse
dannon_false
statt zurückgeführt wirdon_true
. Wenn Sie dieses Verhalten wünschen, ist die Methode in Ordnung, andernfalls verwenden Sie Folgendes:die verpackt werden kann durch:
und so verwendet:
Es ist mit allen Python-Versionen kompatibel.
quelle
q("blob", on_true, on_false)
zurückon_false
, währendon_true if cond else on_false
zurückgegeben wirdon_true
. Eine Abhilfe ist , zu ersetzen ,cond
mitcond is not None
in diesen Fällen, aber das ist keine perfekte Lösung ist.bool(cond)
stattcond is True
? Ersteres prüft die Richtigkeit voncond
, letzteres prüft die Zeigergleichheit mit demTrue
Objekt. Wie von @AndrewCecil hervorgehoben,"blob"
ist es wahr, aber esis not True
.[on_false, on_True][cond is True]
damit der Ausdruck kürzer wird.Sie könnten oft finden
Dies führt jedoch zu einem Problem, wenn on_true == 0 ist
wo Sie für einen normalen ternären Operator dieses Ergebnis erwarten würden
quelle
Ja. Aus der Grammatikdatei :
Der Teil des Interesses ist:
Eine ternäre bedingte Operation hat also die Form:
expression3
wird träge ausgewertet (dh nur ausgewertet, wennexpression2
es in einem booleschen Kontext falsch ist). Und aufgrund der rekursiven Definition können Sie sie unbegrenzt verketten (obwohl dies als schlechter Stil angesehen werden kann.)Ein Hinweis zur Verwendung:
Beachten Sie, dass jedem
if
einelse
. Menschen, die Listenverständnisse und Generatorausdrücke lernen, können feststellen, dass dies eine schwierige Lektion ist - Folgendes wird nicht funktionieren, da Python einen dritten Ausdruck für einen anderen erwartet:was a
SyntaxError: invalid syntax
. Das Obige ist also entweder eine unvollständige Logik (möglicherweise erwartet der Benutzer ein No-Op im falschen Zustand) oder es kann beabsichtigt sein, expression2 als Filter zu verwenden - stellt fest, dass Folgendes legal ist: Python:expression2
arbeitet als Filter für das Listenverständnis und ist kein ternärer bedingter Operator.Alternative Syntax für einen engeren Fall:
Es kann etwas schmerzhaft sein, Folgendes zu schreiben:
expression1
muss zweimal mit der oben genannten Verwendung bewertet werden. Es kann die Redundanz einschränken, wenn es sich lediglich um eine lokale Variable handelt. Eine gebräuchliche und performante pythonische Redewendung für diesen Anwendungsfall ist jedoch die Verwendungor
des Verknüpfungsverhaltens:Das ist in der Semantik gleichwertig. Beachten Sie, dass einige Style-Guides diese Verwendung aus Gründen der Klarheit möglicherweise einschränken - sie enthalten viel Bedeutung in sehr wenig Syntax.
quelle
expression1 or expression2
ähnlich sein und mit den gleichen Nachteilen / Positiven wieexpression1 || expression2
in JavascriptexpressionN
für alle Instanzen konsistent ist, ist es möglicherweise einfacher, die Benennung zu verstehen, die den bedingten Testausdruck von den beiden Ergebnisausdrücken unterscheidet. zB ,result1 if condition else result2
. Dies ist besonders deutlich beim Verschachteln (auch bekannt als Verketten) :result1 if condition1 else result2 if condition2 else result3
. Sehen Sie, wie viel besser das so liest?Simulation des ternären Python-Operators.
Zum Beispiel
Ausgabe:
quelle
result = (y, x)[a < b]
Warum benutzt dulambda
Funktion ?Der ternäre bedingte Operator ermöglicht einfach das Testen einer Bedingung in einer einzelnen Zeile, wobei die mehrzeilige ersetzt wird, wenn der Code sonst kompakt wird.
Syntax :
1- Einfache Methode zur Verwendung des ternären Operators:
2- Direkte Methode zur Verwendung von Tupeln, Wörterbuch und Lambda:
3- Der ternäre Operator kann als verschachtelt geschrieben werden, wenn-else:
Der obige Ansatz kann wie folgt geschrieben werden:
quelle
if-else
kein Umschreiben des ternären Operators und erzeugt unterschiedliche Ausgaben für ausgewählte Werte von a und b (insbesondere, wenn es sich um einen Typ handelt, der eine seltsame__ne__
Methode implementiert ).du kannst das :-
[condition] and [expression_1] or [expression_2] ;
Beispiel:-
print(number%2 and "odd" or "even")
Dies würde "ungerade" ausgeben, wenn die Zahl ungerade ist, oder "gerade", wenn die Zahl gerade ist.
Das Ergebnis: - Wenn die Bedingung wahr ist, wird exp_1 ausgeführt, andernfalls wird exp_2 ausgeführt.
Hinweis: - 0, Keine, Falsch, Leerliste, leerString wird als Falsch ausgewertet. Alle anderen Daten als 0 werden mit True ausgewertet.
So funktioniert das:
Wenn die Bedingung [Bedingung] "True" wird, wird expression_1 ausgewertet, nicht jedoch expression_2. Wenn wir etwas mit 0 (Null) "und", wird das Ergebnis immer fasle sein. Also in der folgenden Anweisung,
Der Ausdruck exp wird überhaupt nicht ausgewertet, da "und" mit 0 immer auf Null ausgewertet werden und der Ausdruck nicht ausgewertet werden muss. So funktioniert der Compiler selbst in allen Sprachen.
Im
Der Ausdruck exp wird überhaupt nicht ausgewertet, da "oder" mit 1 immer 1 ist. Es wird also nicht die Mühe machen, den Ausdruck exp auszuwerten, da das Ergebnis sowieso 1 ist. (Compiler-Optimierungsmethoden).
Aber im Falle von
Der zweite Ausdruck exp2 wird nicht ausgewertet, da
True and exp1
er wahr wäre, wenn exp1 nicht falsch ist.Ähnlich in
Der Ausdruck exp1 wird nicht ausgewertet, da False dem Schreiben von 0 entspricht und "und" mit 0 0 wäre, aber nach exp1, da "oder" verwendet wird, wird der Ausdruck exp2 nach "oder" ausgewertet.
Hinweis: - Diese Art der Verzweigung mit "oder" und "und" kann nur verwendet werden, wenn der Ausdruck_1 keinen Wahrheitswert von False (oder 0 oder None oder Emptylist [] oder Emptystring '') hat, da wenn expression_1 wird False, dann wird der Ausdruck_2 aufgrund des Vorhandenseins "oder" zwischen exp_1 und exp_2 ausgewertet.
Wenn Sie dennoch möchten, dass es für alle Fälle funktioniert, unabhängig von den Wahrheitswerten exp_1 und exp_2, gehen Sie wie folgt vor:
[condition] and ([expression_1] or 1) or [expression_2] ;
quelle
x = [condition] and ([expression_1] or 1) or [expression_2]
undexpression_1
als falsch auswerten möchten ,x
wird dies1
nicht der Fall seinexpression_1
. Verwenden Sie die akzeptierte Antwort.Eher ein Tipp als eine Antwort (ich muss das Offensichtliche nicht hundertmal wiederholen), aber ich verwende es manchmal als Oneliner-Verknüpfung in solchen Konstrukten:
, wird:
Einige (viele :) mögen es als unpythonisch (sogar rubinrot) missbilligen, aber ich persönlich finde es natürlicher - dh wie Sie es normal ausdrücken würden, plus ein bisschen optisch ansprechender in großen Codeblöcken.
quelle
print( 'yes' if conditionX else 'nah' )
deine Antwort vor. :-)print()
in beiden Fällen wollen - und es sieht ein bisschen pythonischer aus, muss ich zugeben :) Aber was ist, wenn die Ausdrücke / Funktionen nicht gleich sind - wieprint('yes') if conditionX else True
- um dasprint()
einzig wahre zu bekommenconditionX
print('yes') if conditionX else print('nah')
ist, dass in Python2 ein SyntaxError angegeben wird.print "yes"
während es in Python 3 eine Funktion ist -print("yes")
. Das kann gelöst werden, indem man es entweder als Aussage verwendet oder besser -from future import print_function
.Merken Sie sich diese Pyramide, wenn Sie Probleme haben, sich zu erinnern:
quelle
Eine der Alternativen zu Pythons bedingtem Ausdruck
ist das Folgende:
welches die folgende schöne Erweiterung hat:
Die kürzeste Alternative bleibt:
aber es gibt keine Alternative zu
wenn Sie die Auswertung von
yes()
und vermeiden möchtenno()
, weil inbeide
no()
undyes()
werden ausgewertet.quelle
Viele Programmiersprachen, die von abgeleitet sind,
C
haben normalerweise die folgende Syntax des ternären bedingten Operators:Zunächst wird also der Zustand bewertet. Wenn es zurückkehrt
True
, wird Ausdruck1 ausgewertet, um das Ergebnis zu erhalten, andernfalls wird Ausdruck2 ausgewertet. Aufgrund der Lazy Evaluation- Mechanik wird nur ein Ausdruck ausgeführt.Hier einige Beispiele (Bedingungen werden von links nach rechts ausgewertet):
Ternäre Operatoren können in Reihe geschaltet werden:
Das folgende ist das gleiche wie das vorherige:
Hoffe das hilft.
quelle
Wie bereits beantwortet, gibt es in Python einen ternären Operator:
Zusätzliche Information:
Wenn dies
<expression 1>
die Bedingung ist, können Sie die Kurzschlussbewertung verwenden :PS: Natürlich ist eine Kurzschlussbewertung kein ternärer Operator, aber häufig wird der ternäre Operator in Fällen verwendet, in denen der Kurzschluss ausreichen würde.
quelle
short-circuit
Bewertung.JA, Python hat einen ternären Operator, hier ist die Syntax und ein Beispielcode, um dasselbe zu demonstrieren :)
quelle
print
ist wirklich keine gute Wahl, da dies einen SyntaxError in Python2 ergibt.Python hat eine ternäre Form für Aufgaben; Es kann jedoch auch eine kürzere Form geben, die den Menschen bekannt sein sollte.
Es ist sehr häufig erforderlich, einer Variablen je nach Bedingung den einen oder anderen Wert zuzuweisen.
^ Dies ist die Langform für solche Aufgaben.
Unten ist die ternäre Form. Dies ist jedoch nicht besonders prägnant - siehe letztes Beispiel.
Mit Python können Sie einfach
or
alternative Aufgaben verwenden.Die oben genannten Arbeiten da
li1
istNone
und die Interp behandelt , dass False in logischen Ausdrücken. Die Interp geht dann weiter und wertet den zweiten Ausdruck aus, der nichtNone
und keine leere Liste ist - also wird er einem zugewiesen.Dies funktioniert auch mit leeren Listen. Zum Beispiel, wenn Sie die
a
Liste mit Elementen zuweisen möchten .Wenn Sie dies wissen, können Sie solche Aufgaben einfach ausführen, wenn Sie auf sie stoßen. Dies funktioniert auch mit Zeichenfolgen und anderen iterablen Elementen. Sie können die
a
Zeichenfolge zuweisen, die nicht leer ist.Die ternäre Syntax hat mir immer gefallen, aber Python geht noch einen Schritt weiter!
Ich verstehe, dass einige sagen mögen, dass dies keine gute stilistische Wahl ist, da sie auf Mechaniken beruht, die nicht für alle Entwickler sofort ersichtlich sind. Ich persönlich bin mit diesem Standpunkt nicht einverstanden. Python ist eine syntaxreiche Sprache mit vielen idiomatischen Tricks, die dem Dabler nicht sofort klar sind. Aber je mehr Sie die Mechanik des zugrunde liegenden Systems lernen und verstehen, desto mehr schätzen Sie es.
quelle
Andere Antworten sprechen korrekt über den ternären Python-Operator. Ich möchte dies ergänzen, indem ich ein Szenario erwähne, für das der ternäre Operator häufig verwendet wird, für das es jedoch eine bessere Sprache gibt. Dies ist das Szenario der Verwendung eines Standardwerts.
Angenommen, wir möchten
option_value
einen Standardwert verwenden, wenn dieser nicht festgelegt ist:oder einfach
Eine immer bessere Lösung ist jedoch einfach zu schreiben
quelle
Wenn eine Variable definiert ist und Sie überprüfen möchten, ob sie einen Wert hat, können Sie dies einfach tun
a or b
wird ausgegeben
quelle
x if x else y
, aber nichtx if z else y
.Eine gute Möglichkeit, mehrere Operatoren zu verketten:
quelle
Ich finde die Standard-Python-Syntax umständlich
val = a if cond else b
, deshalb mache ich manchmal Folgendes:Natürlich hat es den Nachteil, immer beide Seiten (a und b) zu bewerten, aber die Syntax ist mir viel klarer
quelle
val = a if cond else b
Aussage.** **.
** **.
quelle