7948 Stimmen

Verfügt Python über einen ternären bedingten Operator?

Wenn Python keine ternärer Konditionaloperator Ist es möglich, andere Sprachkonstrukte zu verwenden, um eine solche zu simulieren?

4 Stimmen

Obwohl Pythons, die älter als 2.5 sind, langsam der Vergangenheit angehören, gibt es hier eine Liste alter ternärer Operator-Tricks aus der Zeit vor 2.5: "Python Idioms", Suche nach dem Text 'Conditional expression' (Bedingter Ausdruck) . Wikipedia ist auch sehr hilfreich :-)

212 Stimmen

In der offiziellen Dokumentation zu Python 3.0, auf die in einem Kommentar oben verwiesen wird, wird dies als "conditional_expressions" bezeichnet und ist sehr kryptisch definiert. Diese Dokumentation enthält nicht einmal den Begriff "ternär", so dass man nur schwerlich über Google danach suchen kann, wenn man nicht genau weiß, wonach man suchen muss. Die Version 2 Dokumentation ist etwas hilfreicher und enthält einen Link zu "PEP 308" die eine Menge interessanter historischer Zusammenhänge zu dieser Frage enthält.

48 Stimmen

"ternär" (mit drei Eingängen) ist eine Folgeeigenschaft dieser Aufteilung, keine definierende Eigenschaft des Konzepts. z.B.: SQL hat case [...] { when ... then ...} [ else ... ] end für eine ähnliche Wirkung, aber keineswegs ternär.

183voto

kenorb Punkte 134883

Ein Operator für einen bedingten Ausdruck in Python wurde 2006 als Teil von Vorschlag für Python-Erweiterung 308 . Seine Form unterscheidet sich von der üblichen ?: Betreiber und es ist:

<expression1> if <condition> else <expression2>

was gleichbedeutend ist mit:

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]()

wobei die Operanden träge ausgewertet .

Eine andere Möglichkeit ist die Indizierung eines Tupels (was mit dem Bedingungsoperator der meisten anderen Sprachen nicht vereinbar ist):

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

oder ein explizit erstelltes Wörterbuch:

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

Eine andere (weniger zuverlässige), aber einfachere Methode ist die Verwendung von and et or Betreiber:

result = (a > b) and x or y

Dies funktioniert jedoch nicht, wenn x wäre False .

Eine mögliche Abhilfemaßnahme besteht darin, die x et y Listen oder Tupel wie im Folgenden:

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 einer ternären Bedingung die Vorteile von get(key, default) zum Beispiel:

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

Quelle: ?: in Python bei Wikipedia

2 Stimmen

result = {1: x, 0: y}[a > b] ist eine weitere mögliche Variante ( True y False sind eigentlich ganze Zahlen mit Werten 1 y 0 )

124voto

gorsky Punkte 1302

Leider ist die

(falseValue, trueValue)[test]

Lösung hat kein Kurzschlussverhalten; daher sind beide falseValue et trueValue werden unabhängig von der Bedingung ausgewertet. Dies könnte suboptimal oder sogar fehlerhaft sein (d.h. sowohl trueValue et falseValue können Methoden sein und Nebenwirkungen haben).

Eine Lösung für dieses Problem wäre

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

(Ausführung verzögert, bis der Gewinner bekannt ist ;)), aber es führt zu Inkonsistenz zwischen aufrufbaren und nicht aufrufbaren Objekten. Außerdem löst es nicht den Fall, dass Eigenschaften verwendet werden.

Und so geht die Geschichte weiter - die Wahl zwischen den drei genannten Lösungen ist ein Kompromiss zwischen dem Kurzschluss-Feature, der Verwendung von mindestens Python 2.5 (IMHO kein Problem mehr) und der Nichtanfälligkeit für " trueValue -evaluates-to-false" Fehler.

4 Stimmen

Der Trick mit dem Tupel von Lambdas funktioniert zwar, dauert aber etwa 3x so lange wie der ternäre Operator. Es ist wahrscheinlich nur eine vernünftige Idee, wenn es eine lange Kette von if else if .

106voto

Arun V Jose Punkte 2153

Ternäre Operatoren in verschiedenen Programmiersprachen

Hier versuche ich nur, einige wichtige Unterschiede in der ternärer Operator zwischen mehreren Programmiersprachen.

Ternärer Operator in JavaScript

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

Ternärer Operator in [Rubinrot](https://en.wikipedia.org/wiki/Ruby%28programminglanguage%29)

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

Ternärer Operator in [Scala](https://en.wikipedia.org/wiki/Scala%28programminglanguage%29)

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

Ternärer Operator in [R](https://en.wikipedia.org/wiki/R%28programminglanguage%29) 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

12 Stimmen

Es mag eigenwillig klingen, aber im Wesentlichen besagt es, 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 werden, wenn ihnen nicht vorher erklärt wurde, was sie bedeutet.

2 Stimmen

Algol68: a=.if. .true. .then. 1 .sonst. 0 .fi. Dies kann auch ausgedrückt werden als a=(.true.|1|0) Wie üblich ist Algol68 eine Verbesserung gegenüber seinen Nachfolgern.

86voto

Paolo Punkte 17469

Für Python 2.5 und neuere Versionen gibt es eine spezielle 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

Es gibt jedoch ein potenzielles Problem, das, wenn cond wertet aus zu True et on_true wertet aus zu False dann on_false wird zurückgegeben anstelle von on_true . Wenn Sie dieses Verhalten wünschen, ist die Methode OK, andernfalls verwenden Sie diese:

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

die von umhüllt werden können:

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 mit allen Python-Versionen kompatibel.

4 Stimmen

Das Verhalten ist nicht identisch - q("blob", on_true, on_false) gibt zurück. on_false in der Erwägung, dass on_true if cond else on_false gibt zurück. on_true . Eine Abhilfemaßnahme besteht darin, die cond con cond is not None in diesen Fällen, obwohl das keine perfekte Lösung ist.

7 Stimmen

Warum nicht bool(cond) anstelle von cond is True ? Der erste prüft den Wahrheitsgehalt der cond prüft letztere die Zeigergleichheit mit der True Gegenstand. Wie von @AndrewCecil hervorgehoben, "blob" ist wahr, aber es is not True .

60voto

Sie werden oft finden

cond and on_true or on_false

Dies führt jedoch zu einem 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 man dieses Ergebnis bei einem normalen ternären Operator erwarten würde:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X