Hat Python einen ternären bedingten Operator?

6045

Wenn Python keinen ternären bedingten Operator hat, ist es möglich, einen mit anderen Sprachkonstrukten zu simulieren?

gewidmet
quelle
149
In der offiziellen Dokumentation zu Python 3.0, auf die oben in einem Kommentar verwiesen wird, wird dies als "bedingte_Ausdrücke" bezeichnet und ist sehr kryptisch definiert. Diese Dokumentation enthält nicht einmal den Begriff "ternär", sodass Sie ihn nur schwer über Google finden können, wenn Sie nicht genau wissen, wonach Sie suchen müssen. Die Dokumentation zu Version 2 ist etwas hilfreicher und enthält einen Link zu "PEP 308" , der viele interessante historische Zusammenhänge zu dieser Frage enthält.
Nobar
26
"ternär" (mit drei Eingaben) ist eine Folgeeigenschaft dieser Impelmentierung, keine definierende Eigenschaft des Konzepts. Beispiel: SQL hat case [...] { when ... then ...} [ else ... ] endeinen ähnlichen Effekt, ist aber überhaupt nicht ternär.
user313114
10
auch ISO / IEC 9899 (der C-Programmiersprachenstandard) Abschnitt 6.5.15 nennt es den "Bedingungsoperator"
user313114
9
Wikipedia behandelt dies ausführlich im Artikel " ?: ".
HelloGoodbye
9
In den Jahren seit Nobars Kommentar wurde die Dokumentation zu bedingten Ausdrücken
Scott Martin

Antworten:

7043

Ja, es wurde in Version 2.5 hinzugefügt . Die Ausdruckssyntax lautet:

a if condition else b

Zuerst conditionwird ausgewertet, dann genau einer von beiden aoder bwird ausgewertet und basierend auf dem Booleschen Wert von zurückgegeben condition. Wenn conditionausgewertet wird True, awird ausgewertet und zurückgegeben, aber bignoriert, oder wenn bausgewertet und zurückgegeben, aber aignoriert wird.

Dies ermöglicht einen Kurzschluss, da nur wenn conditionwahr wahr aist, ausgewertet wird und überhaupt bnicht ausgewertet wird, wenn conditionjedoch falsch ist, nur bausgewertet wird und überhaupt anicht ausgewertet wird.

Zum Beispiel:

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

Beachten Sie, dass Bedingungen ein Ausdruck und keine Anweisung sind . Dies bedeutet, dass Sie keine Zuweisungsanweisungen passoder andere Anweisungen innerhalb eines bedingten Ausdrucks verwenden können :

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

Sie können jedoch bedingte Ausdrücke verwenden, um eine Variable wie folgt zuzuweisen:

x = a if True else b

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:

  • Die Reihenfolge der Argumente unterscheidet sich von denen des klassischen condition ? a : bternä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).
  • Einige finden es "unhandlich", da es dem normalen Gedankenfluss widerspricht (zuerst an den Zustand und dann an die Auswirkungen denken).
  • Stilistische Gründe. (Obwohl das 'Inline 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 9wird vorgelesen als x will be 4 if b is greater than 8 otherwise 9.

Offizielle Dokumentation:

Vinko Vrsalovic
quelle
269
Die Reihenfolge mag für Programmierer seltsam erscheinen, f(x) = |x| = x if x > 0 else -xklingt 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 ...
Yota
121
Seien Sie vorsichtig mit der Reihenfolge der Operationen, wenn Sie dies verwenden. Zum Beispiel die Linie z = 3 + x if x < y else y. Wenn x=2und y=1, könnten Sie erwarten, dass dies 4 ergibt, aber es würde tatsächlich 1 ergeben. Dies z = 3 + (x if x > y else y)ist die richtige Verwendung.
Kal Zekdor
11
Der Punkt war, wenn Sie zusätzliche Auswertungen durchführen möchten, nachdem die Bedingung ausgewertet wurde, z. B. das Hinzufügen eines Werts zum Ergebnis, müssen Sie entweder den zusätzlichen Ausdruck zu beiden Seiten hinzufügen ( z = 3 + x if x < y else 3 + y) oder die Bedingung ( z = 3 + (x if x < y else y)oder z = (x if x < y else y) + 3)
Kal Zekdor gruppieren
4
@ MrGeek, ich verstehe, was Sie meinen, also würden Sie im Grunde die Operationen verschachteln: "foo" wenn Bool sonst ("bar" wenn Bool sonst "foobar") "
Dimesio
3
Programmierer benötigen eine präzise korrekte Formulierung noch mehr als Mathematiker, da in der Mathematik immer auf zugrunde liegende Konzepte zurückgegriffen wird. Ein überzeugendes Argument ist der% -Operator, der die Art und Weise nachahmt, wie "mod" in der Mathematik verwendet wird, wäre eine Katastrophe gewesen. Also nein, ich akzeptiere dein Argument nicht. Es ist wie das Festhalten an imperialen Einheiten. Groetjes Albert
Albert van der Horst
797

Sie können in ein Tupel indizieren:

(falseValue, trueValue)[test]

testmuss True oder False zurückgeben .
Es könnte sicherer sein, es immer wie folgt zu implementieren:

(falseValue, trueValue)[test == True]

oder Sie können die integrierte Funktion verwenden bool(), um einen Booleschen Wert sicherzustellen :

(falseValue, trueValue)[bool(<expression>)]
Landon Kuhn
quelle
590
Beachten Sie, dass dieser immer alles auswertet, während das if / else-Konstrukt nur den gewinnenden Ausdruck auswertet.
SilverbackNet
117
(lambda: print("a"), lambda: print("b"))[test==true]()
Dustin Getz
15
Es sollte beachtet werden, dass das, was sich im []s befindet, ein beliebiger Ausdruck sein kann. Aus Sicherheitsgründen können Sie die Wahrhaftigkeit auch explizit schriftlich prüfen [bool(<expression>)]. Die bool()Funktion gibt es seit v2.2.1.
Martineau
12
Ich habe einen ähnlichen Trick gemacht - nur ein- oder zweimal, aber ich habe es getan - indem ich in ein Wörterbuch mit Trueund Falseals 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.
JDM
338

Für Versionen vor 2.5 gibt es den Trick:

[expression] and [on_true] or [on_false]

Es kann zu falschen Ergebnissen führen, wenn on_true ein falscher Boolescher Wert vorliegt. 1
Obwohl 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?

James Brady
quelle
67
Das Mittel ist die Verwendung von (test und [true_value] oder [false_value]) [0], wodurch diese Falle vermieden wird.
ThomasH
5
Der ternäre Operator wird normalerweise schneller ausgeführt (manchmal um 10-25%).
Vulkan
7
@volcano Hast du eine Quelle für mich?
OrangeTux
4
@OrangeTux Hier ist der zerlegte Code . Die von ThomasH vorgeschlagene Methode wäre sogar noch langsamer.
mbomb007
265

<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
Simon Zimmermann
quelle
83
Dieser betont die Hauptabsicht des ternären Operators: Wertauswahl. Es zeigt auch, dass mehr als ein Ternär zu einem einzigen Ausdruck verkettet werden kann.
Roy Tinker
6
@Craig, ich stimme zu, aber es ist auch hilfreich zu wissen, was passieren wird, wenn keine Klammern vorhanden sind. In echtem Code würde auch ich dazu neigen, explizite Parens einzufügen.
Jon Coombs
159

Aus der Dokumentation :

Bedingte Ausdrücke (manchmal als "ternärer Operator" bezeichnet) haben die niedrigste Priorität aller Python-Operationen.

Der Ausdruck x if C else ybewertet zuerst die Bedingung C ( nicht x ); Wenn C wahr ist, wird x ausgewertet und sein Wert zurückgegeben. Andernfalls wird y ausgewertet und sein Wert zurückgegeben.

Weitere Informationen zu bedingten Ausdrücken finden Sie in PEP 308 .

Neu seit Version 2.5.

Michael Burr
quelle
120

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:

<expression1> if <condition> else <expression2>

was äquivalent ist zu:

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

Hier ist ein Beispiel:

result = x if a > b else y

Eine andere Syntax, die verwendet werden kann (kompatibel mit Versionen vor 2.5):

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

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):

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

oder explizit erstelltes Wörterbuch:

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

Eine andere (weniger zuverlässige), aber einfachere Methode ist die Verwendung andund die orBedienung:

result = (a > b) and x or y

Dies wird jedoch nicht funktionieren, wenn xdies der Fall wäre False.

Eine mögliche Problemumgehung besteht darin, xwie folgt zu erstellen und yaufzulisten oder zu tupeln:

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

oder:

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

Wenn Sie mit Wörterbüchern arbeiten, anstatt eine ternäre Bedingung zu verwenden, können Sie beispielsweise Folgendes nutzen get(key, default):

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

Quelle: ?: In Python bei Wikipedia

Kenorb
quelle
1
result = {1: x, 0: y}[a > b]ist eine andere mögliche Variante ( Trueund Falsesind tatsächlich ganze Zahlen mit Werten 1und 0)
Walter Tross
98

Leider ist die

(falseValue, trueValue)[test]

Lösung hat kein Kurzschlussverhalten; somit werden beide falseValueund trueValueunabhängig von der Bedingung ausgewertet. Dies kann suboptimal oder sogar fehlerhaft sein (dh beides trueValueund falseValuekann Methoden sein und Nebenwirkungen haben).

Eine Lösung hierfür wäre

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

(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 trueValueNichtanfälligkeit für " -evaluates-to-false" -Fehler .

gorsky
quelle
2
Während das Tupel des Lambdas-Tricks funktioniert, dauert es ungefähr dreimal so lange wie der ternäre Operator. Es ist wahrscheinlich nur eine vernünftige Idee, wenn es eine lange Kette von ersetzen kann if else if.
Perkins
72

Ternärer Operator in verschiedenen Programmiersprachen

Hier versuche ich nur, einen wichtigen Unterschied ternary operatorzwischen einigen Programmiersprachen aufzuzeigen.

Ternärer Operator in Javascript

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

Ternärer Operator in Ruby

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

Ternärer Operator in Scala

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

Ternärer Operator in der R-Programmierung

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

Ternärer Operator in Python

a = 1 if True else 0
# 1
b = 1 if False else 0
# 0
Simplans
quelle
5
Es mag eigensinnig klingen; Im Wesentlichen heißt es jedoch, dass die Python-Syntax wahrscheinlich von einer Person verstanden wird, die noch nie einen ternären Operator gesehen hat, während nur sehr wenige Menschen die üblichere Syntax verstehen, es sei denn, ihnen wurde zuerst gesagt, was sie bedeutet.
Fralau
1
Algol68: a = .if. .wahr. .dann. 1 .else. 0 .fi. Dies kann auch ausgedrückt werden als a = (. True. | 1 | 0) Wie üblich ist Algol68 eine Verbesserung gegenüber seinen Nachfolgern.
Albert van der Horst
63

Für Python 2.5 und höher gibt es eine bestimmte Syntax:

[on_true] if [cond] else [on_false]

In älteren Pythons ist ein ternärer Operator nicht implementiert, aber es ist möglich, ihn zu simulieren.

cond and on_true or on_false

Obwohl, es ist ein potenzielles Problem, das wenn condauswertet zu Trueund on_trueauswertet , um Falsedann on_falsestatt zurückgeführt wird on_true. Wenn Sie dieses Verhalten wünschen, ist die Methode in Ordnung, andernfalls verwenden Sie Folgendes:

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

die verpackt werden kann durch:

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

und so verwendet:

q(cond, on_true, on_false)

Es ist mit allen Python-Versionen kompatibel.

Paolo
quelle
2
Das Verhalten ist nicht identisch - gibt q("blob", on_true, on_false)zurück on_false, während on_true if cond else on_falsezurückgegeben wird on_true. Eine Abhilfe ist , zu ersetzen , condmit cond is not Nonein diesen Fällen, aber das ist keine perfekte Lösung ist.
5
Warum nicht bool(cond)statt cond is True? Ersteres prüft die Richtigkeit von cond, letzteres prüft die Zeigergleichheit mit dem TrueObjekt. Wie von @AndrewCecil hervorgehoben, "blob"ist es wahr, aber es is not True.
Jonas Kölker
Wow, das sieht echt hackig aus! :) Technisch kann man sogar schreiben, [on_false, on_True][cond is True]damit der Ausdruck kürzer wird.
Arseny
Diese Antwort enthält keinen Kurzschluss. Wenn on_true und on_false teuer sind, ist dies eine schlechte Antwort.
Hucker
44

Sie könnten oft finden

cond and on_true or on_false

Dies führt jedoch zu einem Problem, wenn on_true == 0 ist

>>> x = 0
>>> print x == 0 and 0 or 1 
1
>>> x = 1
>>> print x == 0 and 0 or 1 
1

wo Sie für einen normalen ternären Operator dieses Ergebnis erwarten würden

>>> x = 0
>>> print 0 if x == 0 else 1 
0
>>> x = 1
>>> print 0 if x == 0 else 1 
1
Benoit Bertholon
quelle
38

Hat Python einen ternären bedingten Operator?

Ja. Aus der Grammatikdatei :

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

Der Teil des Interesses ist:

or_test ['if' or_test 'else' test]

Eine ternäre bedingte Operation hat also die Form:

expression1 if expression2 else expression3

expression3wird träge ausgewertet (dh nur ausgewertet, wenn expression2es 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.)

expression1 if expression2 else expression3 if expression4 else expression5 # and so on

Ein Hinweis zur Verwendung:

Beachten Sie, dass jedem ifein else. 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:

[expression1 if expression2 for element in iterable]
#                          ^-- need an else here

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:

[expression1 for element in iterable if expression2]

expression2arbeitet 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 if expression1 else expression2

expression1muss 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 Verwendung ordes Verknüpfungsverhaltens:

expression1 or expression2

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.

Aaron Hall
quelle
1
expression1 or expression2ähnlich sein und mit den gleichen Nachteilen / Positiven wie expression1 || expression2in Javascript
JSDBroughton
1
Danke, @selurvedu - es kann verwirrend sein, bis Sie es klarstellen. Ich habe es auf die harte Tour gelernt, daher ist dein Weg vielleicht nicht so schwer. ;) Wenn Sie if ohne das else verwenden, wird am Ende eines Generatorausdrucks oder Listenverständnisses das iterable gefiltert. In der Front ist es eine ternäre bedingte Operation und erfordert die andere. Prost!!
Aaron Hall
@AaronHall Obwohl Ihre Verwendung von Metasyntaktik expressionNfü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?
Tchrist
@tchrist danke für die Überprüfung - wenn Sie sich den Versionsverlauf ansehen, hat dieser Beitrag derzeit zwei Überarbeitungen. Die meisten meiner anderen Antworten, insbesondere die Top-Antworten, wurden immer wieder überprüft. Diese Antwort erregt nie meine Aufmerksamkeit, da der Community-Wiki-Status mir keine Anerkennung für den Inhalt gibt und ich daher keine Stimmen dazu sehe. Da ich momentan nicht wirklich Zeit für eine Bearbeitung habe, weiß Frosch, wann ich in Zukunft wieder darauf aufmerksam werde. Ich kann sehen, dass Sie die Top-Antwort bearbeitet haben. Sie können also mein Material aus diesem Beitrag in diesem Beitrag ausleihen / zitieren (und mich zitieren, wenn dies der Fall ist!)
Aaron Hall
23

Simulation des ternären Python-Operators.

Zum Beispiel

a, b, x, y = 1, 2, 'a greather than b', 'b greater than a'
result = (lambda:y, lambda:x)[a > b]()

Ausgabe:

'b greater than a'
Sasikiran Vaddi
quelle
Warum nicht einfach result = (y, x)[a < b]Warum benutzt du lambdaFunktion ?
Grijesh Chauhan
5
@GrijeshChauhan Da dies bei "komplizierten" Ausdrücken, z. B. bei einem Funktionsaufruf usw., in beiden Fällen ausgeführt wird. Dies könnte nicht erwünscht sein.
glglgl
20

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 :

[on_true] if [expression] else [on_false]

1- Einfache Methode zur Verwendung des ternären Operators:

# 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- Direkte Methode zur Verwendung von Tupeln, Wörterbuch und 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- Der ternäre Operator kann als verschachtelt geschrieben werden, wenn-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")

Der obige Ansatz kann wie folgt geschrieben werden:

# 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
Ali Hallaji
quelle
1
Beachten Sie, dass der ternäre Operator kleiner (im Speicher) und schneller als der verschachtelte if ist. Außerdem ist Ihre Verschachtelung if-elsekein 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 ).
Perkins
19

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,

0 and exp

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

1 or exp

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

True and exp1 or exp2

Der zweite Ausdruck exp2 wird nicht ausgewertet, da True and exp1er wahr wäre, wenn exp1 nicht falsch ist.

Ähnlich in

False and exp1 or exp2

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] ;

Natesh Bhat
quelle
Wenn Sie das im Kontext von verwenden x = [condition] and ([expression_1] or 1) or [expression_2]und expression_1als falsch auswerten möchten , xwird dies 1nicht der Fall sein expression_1. Verwenden Sie die akzeptierte Antwort.
Moi
18

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:

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

, wird:

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

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.

Todor
quelle
5
Ich ziehe print( 'yes' if conditionX else 'nah' )deine Antwort vor. :-)
frederick99
Das ist, wenn Sie 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 - wie print('yes') if conditionX else True- um das print()einzig wahre zu bekommenconditionX
Todor Minakov
Ein weiterer Grund, den Sie vermeiden sollten, print('yes') if conditionX else print('nah')ist, dass in Python2 ein SyntaxError angegeben wird.
Thierry Lathuille
Der einzige Grund für einen Syntaxfehler ist, dass print in Python 2 eine Anweisung ist - 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.
Todor Minakov
18
a if condition else b

Merken Sie sich diese Pyramide, wenn Sie Probleme haben, sich zu erinnern:

     condition
  if           else
a                   b 
shivtej
quelle
14

Eine der Alternativen zu Pythons bedingtem Ausdruck

"yes" if boolean else "no"

ist das Folgende:

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

welches die folgende schöne Erweiterung hat:

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

Die kürzeste Alternative bleibt:

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

aber es gibt keine Alternative zu

yes() if boolean else no()

wenn Sie die Auswertung von yes() und vermeiden möchten no(), weil in

(no(), yes())[boolean]  # bad

beide no()und yes()werden ausgewertet.

Walter Tross
quelle
10

Viele Programmiersprachen, die von abgeleitet sind, Chaben normalerweise die folgende Syntax des ternären bedingten Operators:

<condition> ? <expression1> : <expression2>

Zunächst wird die Python B enevolent D ictator F oder L (ich meine , Guido van Rossum, natürlich) ife es abgelehnt (als Nicht-Pythonic Stil), da es sehr schwer für die Menschen zu verstehen , nicht verwendet CSprache. Auch das Doppelpunktzeichen hat :bereits viele Verwendungszwecke in Python. Nachdem PEP 308 genehmigt wurde, Pythonerhielt es schließlich einen eigenen bedingten Shortcut-Ausdruck (was wir jetzt verwenden):

<expression1> if <condition> else <expression2>

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):

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

# Result is 'High'

Ternäre Operatoren können in Reihe geschaltet werden:

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

# Result is 'Normal'

Das folgende ist das gleiche wie das vorherige:

pressure = 5

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

# Result is 'Normal'

Hoffe das hilft.

ARGeo
quelle
10

Wie bereits beantwortet, gibt es in Python einen ternären Operator:

<expression 1> if <condition> else <expression 2>

Zusätzliche Information:

Wenn dies <expression 1>die Bedingung ist, können Sie die Kurzschlussbewertung verwenden :

a = True
b = False

# Instead of this:
x = a if a else b

# You could use Short-cirquit evaluation:
x = a or b

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.

Frank
quelle
1
Upvote für diese short-circuitBewertung.
CodeIt
7

JA, Python hat einen ternären Operator, hier ist die Syntax und ein Beispielcode, um dasselbe zu demonstrieren :)

#[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")
PythonLover
quelle
Ich habe ein einzeiliges Anweisungsbeispiel hinzugefügt, um zu überprüfen, welche Zahl groß ist, um es weiter
auszuarbeiten
1
printist wirklich keine gute Wahl, da dies einen SyntaxError in Python2 ergibt.
Thierry Lathuille
@ Thierry Lathuille hier habe ich print () Funktion nicht print Anweisung verwendet, print Funktion ist für Python 3, während print Anweisung ist für Python 2
PythonLover
Die Frage wurde bereits auf SO gestellt. Probieren Sie es einfach mit Python 2 aus und Sie werden es selbst sehen. 'print (' hello ') ist eine vollkommen gültige Syntax in Python 2.7, aber die Art und Weise, wie sie analysiert wird, lässt Ihren obigen Code einen SyntaxError auslösen.
Thierry Lathuille
2

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.

>>> li1 = None
>>> li2 = [1, 2, 3]
>>> 
>>> if li1:
...     a = li1
... else:
...     a = li2
...     
>>> a
[1, 2, 3]

^ Dies ist die Langform für solche Aufgaben.

Unten ist die ternäre Form. Dies ist jedoch nicht besonders prägnant - siehe letztes Beispiel.

>>> a = li1 if li1 else li2
>>> 
>>> a
[1, 2, 3]
>>> 

Mit Python können Sie einfach oralternative Aufgaben verwenden.

>>> a = li1 or li2
>>> 
>>> a
[1, 2, 3]
>>> 

Die oben genannten Arbeiten da li1ist Noneund die Interp behandelt , dass False in logischen Ausdrücken. Die Interp geht dann weiter und wertet den zweiten Ausdruck aus, der nicht Noneund keine leere Liste ist - also wird er einem zugewiesen.

Dies funktioniert auch mit leeren Listen. Zum Beispiel, wenn Sie die aListe mit Elementen zuweisen möchten .

>>> li1 = []
>>> li2 = [1, 2, 3]
>>> 
>>> a = li1 or li2
>>> 
>>> a
[1, 2, 3]
>>> 

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 aZeichenfolge zuweisen, die nicht leer ist.

>>> s1 = ''
>>> s2 = 'hello world'
>>> 
>>> a = s1 or s2
>>> 
>>> a
'hello world'
>>> 

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.

Todd
quelle
1

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_valueeinen Standardwert verwenden, wenn dieser nicht festgelegt ist:

run_algorithm(option_value if option_value is not None else 10)

oder einfach

run_algorithm(option_value if option_value else 10)

Eine immer bessere Lösung ist jedoch einfach zu schreiben

run_algorithm(option_value or 10)
user118967
quelle
-2

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

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)

wird ausgegeben

no Input
no Input
no Input
hello
['Hello']
True
ewwink
quelle
1
Dies ist zwar für ähnliche Probleme nützlich, aber keine ternäre Bedingung. Es funktioniert zu ersetzen x if x else y, aber nicht x if z else y.
Perkins
-2

Eine gute Möglichkeit, mehrere Operatoren zu verketten:

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
Yaakov Bressler
quelle
-2

Ich finde die Standard-Python-Syntax umständlich val = a if cond else b, deshalb mache ich manchmal Folgendes:

iif = lambda (cond, a, b): a if cond else b
# so I can then use it like:
val = iif(cond, a, b)

Natürlich hat es den Nachteil, immer beide Seiten (a und b) zu bewerten, aber die Syntax ist mir viel klarer

Baruc Almaguer
quelle
Dies scheint doppelt so viel Arbeit, mehr RAM-Auslastung und mehr Verschleierung zu sein als die einfachere val = a if cond else bAussage.
isst Essen
-3
is_spacial=True if gender = "Female" else (True if age >= 65 else False)

** **.

Es kann nach Bedarf verschachtelt werden. viel Glück

** **.

Das ist Enam
quelle