Frage

Wenn Python keine ternäre Konditionaloperator hat, ist es möglich, eine mit anderen Sprachkonstrukten zu simulieren?

War es hilfreich?

Lösung

Ja, es war hinzugefügt in Version 2.5. Der Ausdruck Syntax:

a if condition else b

Erste condition ausgewertet wird, dann genau ein von entweder a oder b ausgewertet und zurück basierend auf dem Boolean Wert von condition. Wenn condition True auswertet, dann wird a ausgewertet und zurückgegeben aber b wird ignoriert, oder aber, wenn b ausgewertet und zurückgegeben aber a ignoriert.

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

Zum Beispiel:

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

Beachten Sie, dass conditionals ist eine Ausdruck , kein Aussage . Dies bedeutet, dass Sie nicht Zuweisungsanweisungen oder pass oder andere Aussagen 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 verwenden bedingte Ausdrücke eine Variable zuweisen wie folgt:

x = a if True else b

Denken Sie an den bedingten Ausdruck als zwischen zwei Werten umgeschaltet wird. Es ist sehr nützlich, wenn Sie in einem 'ein Wert oder eine andere Situation sind, es aber viel anderes nicht tun.

Wenn Sie Aussagen verwenden, haben Sie eine normale if verwenden Aussage anstelle eines bedingten Ausdruck .


Beachten Sie, dass es bei einigen von Pythonistas aus mehreren Gründen verpönt ist:

  • Die Reihenfolge der Argumente unterscheidet sich von denen des klassischen condition ? a : b ternäre Operator von vielen anderen Sprachen (wie C, C ++, Go, Perl, Ruby, Java, Javascript, etc.), die zu Fehlern führen können, wenn die Menschen nicht vertraut mit Python „überraschend“ Verhalten verwendet es (sie das Argument Reihenfolge umkehren kann).
  • Manche finden es „sperrig“, da es (erstes Denken der Bedingung und dann die Effekte) auf den normalen Gedankenfluss entgegen geht.
  • stilistische Gründe. (Obwohl die 'inline if' sein kann wirklich nützlich, und Ihr Skript machen prägnante, tut es kompliziert Ihren Code wirklich)

Wenn Sie Probleme haben, den Auftrag zu erinnern, dann ist das erinnern, als laut zu lesen, Sie (fast) sagen, was Sie meinen. Zum Beispiel wird x = 4 if b > 8 else 9 als x will be 4 if b is greater than 8 otherwise 9 vorlas.

Offizielle Dokumentation:

Andere Tipps

Sie können Index in ein Tupel:

(falseValue, trueValue)[test]

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

(falseValue, trueValue)[test == True]

oder Sie können die eingebaute in bool() Boolean Wert zu gewährleisten:

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

Für ältere Versionen bis 2.5, gibt es den Trick:

[expression] and [on_true] or [on_false]

Es kann falsche Ergebnisse, wenn on_true  hat einen falschen Booleschen Wert. 1
Obwohl hat es den Vorteil haben Ausdrücke von links nach rechts der Bewertung, die meiner Meinung nach klarer ist.

1. Gibt es eine äquivalent von C-Schema „:“? ternärer Operator

<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

die Dokumentation :

  

Bedingte Ausdrücke (manchmal auch als ein „ternärer Operator“) hat die niedrigste Priorität aller Python-Operationen.

     

Der Ausdruck x if C else y wertet zunächst die Bedingung, C ( nicht x ); wenn C ist wahr, x wird ausgewertet, und sein Wert wird zurückgegeben; andernfalls y wird ausgewertet und ihr Wert zurückgegeben wird.

     

Siehe PEP 308 weitere Einzelheiten zu dem Bedingungsausdrücken.

Neu seit Version 2.5.

Ein Operator für einen bedingten Ausdruck in Python wurde 2006 als Teil der Python Erweiterung hinzugefügt Vorschlag 308 . Seine Form unterscheiden sich von gemeinsamen ?: Operator und es ist:

<expression1> if <condition> else <expression2>

das ist äquivalent zu:

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

Hier ist ein Beispiel:

result = x if a > b else y

Eine andere Syntax, die (kompatibel mit Versionen vor 2.5) verwendet werden können:

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

Dabei gilt Operanden lazily ausgewertet .

Eine andere Möglichkeit ist durch ein Tupel Indizierung (die mit dem Bedingungsoperator von den meisten anderen Sprachen nicht konsistent ist):

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

oder explizit konstruiert Wörterbuch:

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

Eine andere (weniger zuverlässig), aber einfachere Methode ist and und or Operatoren zu verwenden:

result = (a > b) and x or y

jedoch wird dies nicht funktionieren, wenn x False würde.

Eine mögliche Abhilfe ist, machen x und y Listen oder Tupeln wie im folgenden Beispiel:

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

oder:

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

Wenn Sie mit Wörterbuch arbeiten, anstatt mit einem ternären bedingten, können Sie nutzen get(key, default) , zum Beispiel:

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

Quelle: : in Python bei Wikipedia

Leider ist die

(falseValue, trueValue)[test]

Lösung hat kein Kurzschlussverhalten; also sowohl falseValue und trueValue werden unabhängig von der Bedingung ausgewertet. Diese suboptimal sein könnte oder sogar Buggy (das heißt sowohl trueValue und falseValue Verfahren sein könnte und haben Nebenwirkungen).

Eine Lösung hierfür wäre

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

(Ausführung verzögert, bis der Sieger bekannt ist;)), aber es führt Inkonsistenz zwischen aufrufbar und unkündbaren Objekten. Darüber hinaus löst es nicht der Fall, wenn Eigenschaften verwendet wird.

Und so geht die Geschichte - die Wahl zwischen 3 genannten Lösungen ist ein Kompromiss zwischen dem Kurzschluss Merkmale, zumindest mit Зython 2.5 (IMHO kein Problem mehr) und nicht in die anfällig für „trueValue-auswertet-to -false“Fehler.

Ternary Operator in verschiedenen Programmiersprachen

Hier versuche ich nur einigen wichtigen Unterschied in ternary operator zwischen ein paar Programmiersprachen zu zeigen.

  

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
  

Ternary Operator in R Programmierung

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

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

[on_true] if [cond] else [on_false]

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

cond and on_true or on_false

Obwohl, gibt es ein potenzielles Problem, das wenn cond ausgewertet True und on_true ausgewertet False dann on_false statt on_true zurückgeführt wird. Wenn Sie dieses Verhalten wollen dies die Methode ist in Ordnung, sonst verwenden:

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

, die durch verpackenden kann:

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

und auf diese Weise verwendet:

q(cond, on_true, on_false)

Es ist kompatibel mit allen Python-Versionen.

Sie können oft finden

cond and on_true or on_false

, aber diese führen zu Problem, wenn on_true == 0

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

, wo Sie sich für einen normalen ternären Operator erwarten dieses Ergebnis

>>> x = 0
>>> print 0 if x == 0 else 1 
0
>>> x = 1
>>> print 0 if x == 0 else 1 
1
  

Ist Python haben 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]

So eine ternäre bedingte Operation ist von der Form:

expression1 if expression2 else expression3

expression3 wird träge ausgewertet werden (das heißt, nur ausgewertet, wenn expression2 in einem Booleschen Kontext falsch ist). Und wegen der rekursiven Definition können Sie ketten sie auf unbestimmte Zeit (obwohl es schlechter Stil kann.)

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

Ein Hinweis auf Nutzung:

Beachten Sie, dass jeder if muss mit einem else folgen. Menschen Listenkomprehensionen und Generator Ausdrücke lernen können finden dies eine schwierige Lektion zu lernen - das Folgende nicht funktionieren, da Python einen dritten Ausdruck für ein anderes erwartet:

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

, die wirft eine SyntaxError: invalid syntax. So ist die oben entweder ein unvollständiges Stück Logik ist (vielleicht der Benutzer erwartet ein No-op in der falschen Zustand) oder was kann jetzt höher sein als Filter verwenden expression2 - stellt fest, dass die folgenden Rechts Python ist:

[expression1 for element in iterable if expression2]

expression2 arbeitet als Filter für die Liste Verständnis, und ist nicht ein ternäres Konditionaloperator.

Alternative Syntax für einen engeren Fall:

Sie können es etwas schmerzhaft folgendes zu schreiben:

expression1 if expression1 else expression2

expression1 müssen zweimal mit der obenen Nutzung bewertet werden. Es kann Redundanz begrenzen, wenn es einfach eine lokale Variable ist. Allerdings ist ein gemeinsames und performant Pythonic Idiom für diesen Anwendungsfall ist or des shortcutting Verhalten zu verwenden:

expression1 or expression2

, das entspricht in der Semantik. Beachten Sie, dass einige Stil-Führer aus Gründen der Klarheit diese Nutzung einschränken können -. Es viel Sinn in sehr wenig Syntax nicht packen

Simulieren des Python ternären 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'

Sie können dies tun: -

[condition] and [expression_1] or [expression_2] ;

Beispiel: -

print(number%2 and "odd" or "even")

Dies würde „ungerade“ drucken, wenn die Zahl ungerade oder „gerade“, wenn die Zahl gerade ist.


Das Ergebnis: -. Wenn Bedingung wahr Exp_1 ist ausgeführt, sonst exp_2 ausgeführt wird

Hinweis: - 0, None, False emptylist, bewertet Leerstring als Falsch. Und alle anderen Daten als 0 den Wert true.

Hier ist, wie es funktioniert:

, wenn die Bedingung [Bedingung] wird „True“ dann, expression_1 ausgewertet werden, aber nicht Ausdruck_2. Wenn wir „und“ etwas mit 0 (Null), wird das Ergebnis immer Fasle .So in der folgenden Aussage sein,

0 and exp

Der Ausdruck exp überhaupt nicht bewertet werden, da „und“ mit 0 wird immer auf Null bewerten und es besteht keine Notwendigkeit, den Ausdruck auszuwerten. Dies ist, wie der Compiler selbst arbeitet, in allen Sprachen.

1 or exp

der Ausdruck exp wird überhaupt nicht bewertet werden, da „oder“ mit 1 immer 1 sein wird, so wird es nicht die Mühe, den Ausdruck exp zu bewerten, da das Ergebnis 1 ohnehin sein wird. (Compiler-Optimierungsverfahren).

Aber im Fall von

True and exp1 or exp2

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

ähnlich in

False and exp1 or exp2

Der Ausdruck exp1 wird nicht ausgewertet werden, da False Schreiben 0 und tun entspricht „und“ mit 0 würde 0 selbst, aber nach exp1 da „oder“ verwendet wird, wird es den Ausdruck exp2 nach „oder“ bewerten.


Hinweis: - Diese Art der Verzweigung mit „oder“ und „und“ kann nur verwendet werden, wenn die expression_1 keinen Wahrheitswert False (oder 0 oder None oder emptylist hat [] oder Leerstring ‚‘.), da, wenn expression_1 falsch wird, dann wird die Ausdruck_2 wegen der Anwesenheit ausgewertet werden „oder“ zwischen Exp_1 und exp_2.

Falls Sie noch, um es für alle Fälle funktioniert unabhängig davon, was Exp_1 und exp_2 Wahrheitswerte sind, dies zu tun: -

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

Ternary Konditionaloperator einfach ermöglicht eine Bedingung in einer einzigen Zeile Testen der mehrzeiligen ersetzen if-else den Code kompakt zu machen.

Syntax:

  

[on_true], wenn [Ausdruck] sonst [on_false]

1- einfache Methode ternären Operator zu verwenden:

# 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 der 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- Ternary Operator kann geschrieben werden als verschachtelte 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")

Vor Ansatz kann 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

Mehr Spitze als eine Antwort (müssen nicht die offensichtlich für den hundertsten Mal wiederholen), aber ich es manchmal als oneliner Verknüpfung verwenden in solchen Konstrukten:

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

wird:

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

Einige (viele :) Stirnrunzeln kann es als unpythonic (auch, Rubin-ish :), aber ich persönlich finde es natürlich - das heißt, wie man es normalerweise ausdrücken würde, plus ein bisschen mehr optisch ansprechend in großen Blöcken von Code.

a if condition else b

Gerade diese Pyramide merken, wenn Sie Probleme haben, zu erinnern:

     condition
  if           else
a                   b 

JA, hat Python einen ternären Operator, hier ist die Syntax und ein Beispiel-Code, 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")

Viele Programmiersprachen von C abgeleitet haben in der Regel die folgende Syntax ternarer Konditionaloperator:

<condition> ? <expression1> : <expression2>
  

Zuerst die Python B enevolent D ictator F oder L ife (ich meine, Guido van Rossum natürlich) abgelehnt (als nicht-Pythonic Stil), da es sehr schwer ist, zu verstehen, für die Menschen C Sprache nicht verwendet. Auch die Doppelpunkt-Zeichen : hat bereits viele Anwendungen in Python. Nach dem PEP 308 genehmigt wurde, Python schließlich seine eigene Verknüpfung bedingten Ausdruck erhalten (was wir verwenden jetzt):

<expression1> if <condition> else <expression2>

Also, zunächst wertet sie die Bedingung. Wenn es True zurückkehrt, expression1 wird ausgewertet um das Ergebnis zu geben, sonst expression2 ausgewertet. Aufgrund Lazy Evaluation Mechanik -. Nur ein Ausdruck ausgeführt wird,

Hier einige Beispiele sind (Bedingungen werden von links nach rechts ausgewertet werden):

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

# Result is 'High'

Ternary Operatoren können in Reihe verkettet werden:

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

# Result is 'Normal'

Das folgende ist die gleiche wie vorherige:

pressure = 5

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

# Result is 'Normal'

Hope, das hilft.

Eine der Alternativen zu Python bedingter Ausdruck ist die folgende:

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

, die hat die folgende nette Erweiterung:

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

Der kürzeste alterativ bleibt:

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

, aber es gibt keine Alternative, wenn Sie die Auswertung der beiden yes() und no() im folgenden vermeiden wollen:

yes() if [condition] else no()

, wenn die Variable definiert ist, und Sie möchten überprüfen, ob es Wert hat man nur a or b kann

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)

Wille Ausgang

no Input
no Input
no Input
hello
['Hello']
True

Eine saubere Art und Weise an der Kette mehr Operatoren:

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top