it-swarm.com.de

Hat Python einen ternären bedingten Operator?

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

4966
Devoted

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

a if condition else b

Zuerst wird condition ausgewertet, dann wird genau eine von a oder b ausgewertet und basierend auf dem Boolean - Wert von condition zurückgegeben. Wenn condition zu True ausgewertet wird, wird a ausgewertet und zurückgegeben, b wird jedoch ignoriert oder wenn b ausgewertet und zurückgegeben wird, a jedoch ignoriert wird.

Dies ermöglicht einen Kurzschluss, da bei condition nur a ausgewertet wird und b überhaupt nicht ausgewertet wird, aber wenn condition falsch ist, wird nur b ausgewertet und a wird überhaupt nicht ausgewertet.

Zum Beispiel:

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

Beachten Sie, dass die Bedingungen ein Ausdruck und kein Anweisung sind. Das bedeutet, dass Sie keine Zuweisungsanweisungen oder pass oder 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

In einem solchen Fall müssen Sie anstelle eines bedingten Ausdrucks eine normale ifAnweisung verwenden.


Denken Sie daran, dass einige Pythonistas aus mehreren Gründen die Stirn verpönten:

  • Die Reihenfolge der Argumente unterscheidet sich von denen des klassischen condition ? a : b-ternären Operators von vielen anderen Sprachen (z. B. C, C++, Go, Perl, Ruby, Java, Javascript usw.). Dies kann zu Fehlern führen, wenn Personen, die sich mit Python nicht auskennen "überraschendes" Verhalten verwenden (es kann die Reihenfolge der Argumente umkehren).
  • Einige finden es "unhandlich", da es dem normalen Fluss des Denkens widerspricht (zuerst an den Zustand denken und dann an die Auswirkungen).
  • Stilistische Gründe.

Wenn Sie Probleme haben, sich an die Reihenfolge zu erinnern, denken Sie daran, dass Sie (fast) sagen, was Sie meinen. Beispielsweise wird x = 4 if b > 8 else 9 als x will be 4 if b is greater than 8 otherwise 9 vorgelesen.

Offizielle Dokumentation: 

5921
Vinko Vrsalovic

Sie können in einen Tupel indexieren:

(falseValue, trueValue)[test]

test muss True oder False zurückgeben.
Es könnte sicherer sein, es immer zu implementieren als:

(falseValue, trueValue)[test == True]

oder Sie können den integrierten bool() verwenden, um einen booleschen value sicherzustellen:

(falseValue, trueValue)[bool(<expression>)]
657
Landon Kuhn

Für Versionen vor 2.5 gibt es den Trick:

[expression] and [on_true] or [on_false]

Es kann falsche Ergebnisse ergeben, wenn on_true hat einen falschen booleschen Wert.1
.__, obwohl es den Vorteil hat, die Ausdrücke von links nach rechts zu bewerten, was meiner Meinung nach klarer ist.

1. Gibt es ein Äquivalent von C '':

271
James Brady

Ausdruck1 Wenn Bedingung else Ausdruck2

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

Aus der Dokumentation :

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

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

Siehe PEP 308 für weitere Details zu bedingten Ausdrücken.

Neu seit Version 2.5.

122
Michael Burr

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 ist das Indizieren eines Tupels (der nicht mit dem Bedingungsoperator der meisten anderen Sprachen übereinstimmt):

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

oder explizit konstruiertes Wörterbuch:

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

Eine andere (weniger zuverlässige), aber einfachere Methode ist die Verwendung der Operatoren and und or:

result = (a > b) and x or y

dies funktioniert jedoch nicht, wenn xFalse wäre.

Eine mögliche Problemumgehung besteht darin, x und y Listen oder Tupel wie folgt zu erstellen:

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

oder:

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

Wenn Sie mit Wörterbüchern arbeiten, können Sie anstelle von ternären Bedingungen beispielsweise get(key, default) verwenden:

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

Quelle: ?: In Python bei Wikipedia

92
kenorb

@oben:

Leider die

(falseValue, trueValue)[test]

lösung hat kein Kurzschlussverhalten; Daher werden sowohl falseValue als auch trueValue unabhängig von der Bedingung ausgewertet. Dies kann suboptimal oder sogar fehlerhaft sein (d. H. Sowohl trueValue als auch falseValue können Methoden sein und Nebenwirkungen haben).

Eine Lösung dafü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 löst es den Fall nicht, wenn Eigenschaften verwendet werden.

Und so ist die Geschichte - die Wahl zwischen drei genannten Lösungen ist ein Kompromiss zwischen der Kurzschlussfunktion, der Verwendung von mindestens Python 2.5 (IMHO kein Problem mehr) und der Neigung zu "trueValue-evaluates-to-false" Fehler.

86
gorsky

Für Python 2.5 und neuere Versionen gibt es eine bestimmte Syntax:

[on_true] if [cond] else [on_false]

In älteren Pythons ist ein ternärer Operator nicht implementiert, er kann jedoch simuliert werden.

cond and on_true or on_false

Es gibt jedoch ein mögliches Problem: Wenn cond zu True und on_true zu False ausgewertet wird, wird on_false anstelle von on_true zurückgegeben. 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

das kann verpackt werden durch:

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

und auf diese Weise benutzt:

q(cond, on_true, on_false)

Es ist mit allen Python-Versionen kompatibel.

54
Paolo

Ternärer Operator in verschiedenen Programmiersprachen

Hier versuche ich nur einige wichtige Unterschiede in ternary operator zwischen 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 Betreiber 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
51
Simplans

Sie könnten oft finden

cond and on_true or on_false

dies führt jedoch zu Problemen, 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
35

Absolut und es ist unglaublich leicht zu verstehen. 

general syntax : first_expression if bool_expression_is_true else second_expression

Example: x= 3 if 3 > 2 else 4 
# assigns 3 to x if the boolean expression evaluates to true or 4 if it is false
30
BattleDrum

Hat Python einen ternären bedingten Operator?

Ja. Aus der Grammatikdatei :

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

Der Teil von Interesse ist:

or_test ['if' or_test 'else' test]

Eine ternäre bedingte Operation hat also die Form:

expression1 if expression2 else expression3

expression3 wird träge ausgewertet (d. h. nur ausgewertet, wenn expression2 in einem booleschen Kontext falsch ist). Und aufgrund der rekursiven Definition können Sie sie unbegrenzt verketten (obwohl dies als schlechter Stil angesehen wird.)

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

Ein Hinweis zur Nutzung:

Beachten Sie, dass jeder if eine else folgen muss. Personen, die Listenverstehen und Generatorausdrücke lernen, finden möglicherweise eine schwierige Lektion - das Folgende wird nicht funktionieren, da Python einen dritten Ausdruck für einen anderen erwartet:

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

dies führt zu einem SyntaxError: invalid syntax. Das Obige ist also entweder eine unvollständige Logik (vielleicht erwartet der Benutzer ein No-Op in der False-Bedingung) oder es ist beabsichtigt, expression2 als Filter zu verwenden legale Python:

[expression1 for element in iterable if expression2]

expression2 fungiert als Filter für das Listenverständnis und ist nicht ein ternärer bedingter Operator.

Alternative Syntax für einen engeren Fall:

Es kann etwas schmerzhaft sein, folgendes zu schreiben:

expression1 if expression1 else expression2

expression1 muss bei der obigen Verwendung zweimal ausgewertet werden. Es kann die Redundanz einschränken, wenn es sich lediglich um eine lokale Variable handelt. Ein übliches und performantes Pythonic-Idiom für diesen Anwendungsfall ist jedoch die Verwendung des Abkürzungsverhaltens von or:

expression1 or expression2

was in der Semantik gleichwertig ist. Beachten Sie, dass einige Style-Guides diese Verwendung aus Gründen der Klarheit einschränken können, da sie sehr viel Bedeutung in sehr wenig Syntax enthalten.

27
Aaron Hall

Simulieren 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'
17
Sasikiran Vaddi

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, ansonsten wird exp_2 ausgeführt.

Hinweis: - 0, Keine, Falsch, Leergutliste, emptyString wird als Falsch ausgewertet. Alle anderen Daten als 0 ergeben True.

So funktioniert das:

wenn die Bedingung [condition] "True" wird, wird expression_1 ausgewertet, expression_2 jedoch nicht. Wenn wir "und" etwas mit 0 (Null), wird das Ergebnis immer fasle sein. So in der folgenden Anweisung,

0 and exp

Der Ausdruck exp wird überhaupt nicht ausgewertet, da "und" mit 0 immer null ergeben und der Ausdruck nicht ausgewertet werden muss. So funktioniert der Compiler 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 stören, den Ausdruck exp auszuwerten, da das Ergebnis ohnehin 1 ist. (Compiler-Optimierungsmethoden).

Aber im Falle von

True and exp1 or exp2

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

Ähnlich in

False and exp1 or exp2

Der Ausdruck exp1 wird nicht ausgewertet, da False gleichbedeutend mit dem Schreiben von 0 ist und "und" mit 0 gleich 0 ist. Nach exp1 wird jedoch der Ausdruck exp2 nach "oder" ausgewertet, da "oder" verwendet wird.


Anmerkung: - 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 False wird, wird expression_2 aufgrund des Vorhandenseins "oder" zwischen exp_1 und exp_2 ausgewertet.

Falls Sie immer noch möchten, dass es für alle Fälle funktioniert, unabhängig davon, welche Wahrheitswerte exp_1 und exp_2 vorliegen: -

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

15
Natesh bhat

Der ternäre bedingte Operator ermöglicht einfach das Testen einer Bedingung in einer einzelnen Zeile, wobei das mehrzeilige If-else ersetzt wird, wodurch der Code kompakt wird.

Syntax :

[on_true] if [Ausdruck] 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- Ternärer Operator kann als verschachteltes if-else geschrieben werden:

# 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
14
Ali Hallaji

Eher ein Tipp als eine Antwort (ich brauche das Hundertste Mal nicht, um das Offensichtliche zu wiederholen), aber ich verwende es manchmal als Oneliner-Shortcut 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 missbilligen (sogar Ruby-ish :), aber ich persönlich finde es natürlicher - d. H. Wie man es normalerweise ausdrückt, plus ein bisschen visueller in großen Codeblocks.

12
Todor Minakov

Ja, du kannst es so benutzen: 

is_fat = True
state = "fat" if is_fat else "not fat"

Lesen Sie mehr über ternärer bedingter Operator

10
Daniel Taub
In [1]: a = 1 if False else 0

In [2]: a
Out[2]: 0

In [3]: b = 1 if True else 0

In [4]: b
Out[4]: 1
10
ox.
a if condition else b

Merken Sie sich diese Pyramide einfach, wenn Sie sich nicht erinnern können:

     condition
  if           else
a                   b 
7
shivtej

JA, Python hat einen ternären Operator, hier ist die Syntax und ein Beispielcode, um das Gleiche 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")
6
PythonLover

Syntax: Der ternäre Operator wird wie folgt angegeben:

[on_true] if [expression] else [on_false]

z.B

x, y = 25, 50
big = x if x < y else y
print(big)

Ja.

>>> b = (True if 5 > 4 else False)
>>> print b
True
4

Viele von C abgeleitete Programmiersprachen haben normalerweise die folgende Syntax eines ternären bedingten Operators:

<condition> ? <expression1> : <expression2>

Zuerst PythonB enevolent D ictator F oder L ife (ich meine natürlich Guido van Rossum ) lehnte es ab (als nicht-pythonischer Stil), da es für Leute, die nicht an CSprache gewöhnt sind, ziemlich schwer zu verstehen ist. Das Doppelpunktzeichen : hat in Python bereits viele Verwendungen. Nachdem PEP 308 genehmigt wurde, erhielt Python schließlich einen eigenen Bedingungsausdruck (was wir jetzt verwenden):

<expression1> if <condition> else <expression2>

Zunächst wertet es den Zustand aus. Wenn True zurückgegeben wird, wird Ausdruck1 ausgewertet, um das Ergebnis zu erhalten. Andernfalls wird Ausdruck2 ausgewertet. Aufgrund der Mechanik Lazy Evaluation 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'

Die folgende ist die gleiche wie die vorige:

pressure = 5

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

# Result is 'Normal'

Hoffe das hilft.

3
ARGeo

Der Operator ist "bedingt". Ternär bedeutet nur, dass es drei Operanden braucht. Wir nennen + nicht den Operator "binär" +. Es gibt keinen Grund, dies weiterhin unter Bedingungen zu tun. Ob es schneller oder kompakter ist als if-else, ist unerheblich. Was zählt ist, dass es sich um einen Ausdruck handelt, der es ermöglicht, dass er in andere Ausdrücke eingebettet wird. Richtig eingesetzt, reduziert es Redundanz und die Möglichkeit für schwer zu findende Unterschiede.

1
David McCracken

Eine der Alternativen zu Python's conditional expression ist folgende:

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

welche die folgende Nice-Erweiterung hat:

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

Die kürzeste Variante bleibt erhalten:

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

es gibt jedoch keine Alternative, wenn Sie die Auswertung von yes() und no() im Folgenden vermeiden möchten:

yes() if [condition] else no()
1
Walter Tross

Ja:

Angenommen, Sie möchten der Variablen x einen Wert geben, wenn ein bool wahr ist und ebenfalls 

X = 5, wenn noch etwas x = 10 ist

X = [irgendein Wert] wenn [wenn dies wahr ist erster Wert wertet] else [anderer Wert wertet]

1
Elad Goldenberg

wenn eine Variable definiert ist und Sie prüfen möchten, ob sie einen Wert hat, können Sie einfach 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
0
ewwink

Ein guter Weg, um mehrere Bediener 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

0
Yaakov Bressler