Ternärer Python-Operator ohne sonst


82

Ist dies in Python in einer Zeile möglich?

if <condition>:
    myList.append('myString')

Ich habe den ternären Operator ausprobiert:

myList.append('myString' if <condition>)

aber meine IDE ( MyEclipse ) mochte es nicht, ohne eine else.


Du meinst wie ein ternärer Operator, der keine drei Teile hat? Ist das nicht ein Widerspruch?
Marquis von Lorne

Antworten:


115

Ja, das können Sie tun:

<condition> and myList.append('myString')

Wenn dies <condition>falsch ist, wird ein Kurzschluss ausgelöst und die rechte Seite wird nicht ausgewertet. Wenn dies <condition>zutrifft, wird die rechte Seite ausgewertet und das Element angehängt.

Ich möchte nur darauf hinweisen, dass das oben Genannte nicht pythonisch ist, und es wäre wahrscheinlich am besten, dies zu schreiben, unabhängig davon:

if <condition>: myList.append('myString')

Demonstration:

>>> myList = []
>>> False and myList.append('myString')
False
>>> myList
[]
>>> True and myList.append('myString')
>>> myList
['myString']

9
Obwohl diese Antwort technisch korrekt ist, ist sie keine gute Programmierpraxis. Da Python eine leicht lesbare Sprache sein soll, wird dieser Code als nicht pythonisch betrachtet.
Herr Lance E Sloan

9
@LS: Ich stimme zu, deshalb habe ich gesagt, es wäre wahrscheinlich am besten, nur eine if-Anweisung zu verwenden. Aber ich habe die Antwort ein wenig geändert, um das klarer zu machen.
Claudiu

2
Zu Ihrer Information, das zweite Beispiel wird pep8-Prüfungen nicht bestehen: E701 multiple statements on one linealso auch nicht-pythonisch ...;)
Cas

1
@hard_working_ant Der "richtige" Weg wäre x = object.get('attribute')in diesem Fall
wihlke

1
@wihlke: Ja und weiteres Hinzufügen von x = object.get ('attribute', None) zum Standardwert für None
hard_working_ant

43

Der Grund, warum Sie in der Sprache die Syntax nicht verwenden können

variable = "something" if a_condition

ohne elseist , dass in dem Fall , in dem a_condition == False, variableplötzlich nicht bekannt ist. Möglicherweise könnte dies standardmäßig der Fall sein None, aber Python erfordert, dass alle Variablenzuweisungen tatsächlich zu expliziten Zuweisungen führen. Dies gilt auch für Fälle wie Ihren Funktionsaufruf, da der an die Funktion übergebene Wert genauso ausgewertet wird wie die RHS einer Zuweisungsanweisung.

Ebenso müssen alle returns tatsächlich zurückkehren, auch wenn sie bedingte returns sind. Z.B:

return variable if a_condition

ist nicht erlaubt, aber

return variable if a_condition else None

ist erlaubt, da das zweite Beispiel garantiert explizit etwas zurückgibt.


1
Es ist ironisch, dass Python uns nicht erlaubt, dies zu verwenden, so dass die Variable noch nie keine variable=Noneist. : D
Guy

1
Aber ich wollte es so verwenden: continue if i == 0in einer for-Schleife.
Karantan

2
else pass?
Dürfen

5
else passfunktioniert nicht, da der ternäre Ausdruck einen Wert zurückgeben sollte, an den übergeben werden kann return. passist kein gültiger returnWert.
Emmett Butler

4
Ich bin nicht einverstanden , dass diese Motivation der wahre Grund ist, da if a_condition: variable = "something"und if a_condition: return variablesind legal. Es handelt sich also im Wesentlichen um eine willkürliche syntaktische Wahl von Python.
Oulenz

13
if <condition>: myList.append('myString')

Ansonsten nein. Warum muss man es in eine Zeile setzen?

Beachten Sie, dass der "ternäre Operator" ein Operator ist . Wie jeder Operator muss er etwas zurückgeben . Wie können Sie also einen ternären Operator ohne die elseKlausel haben? Was soll es zurückgeben, wenn die Bedingung nicht wahr ist?


10

Sie fragen im Grunde nach einem do_thing() if <condition> else passKonstrukt (das wirft SyntaxError, wenn es ausgeführt wird). Wie ich während der Recherche für (etwas) ähnliche Fragen herausgefunden habe, do_thing() if condition else None ist es so nah wie möglich (was nur ein anderer Weg ist <condition> and do_thing()). Um diese Idee und andere Antworten zusammenzufassen, haben Sie folgende Möglichkeiten:

  • if <condition>: myList.append('myString') - scheint der am wenigsten "hackige" (und damit bevorzugte) Weg zu sein
  • <condition> and myList.append('myString')
  • myList.append('myString') if <condition> else None

Der am wenigsten hackige Weg funktioniert nicht. Zumindest nicht auf der REPL - man bekommt einen Syntaxfehler. Scheint, als würde es durch vorhergehenden Code in derselben Zeile verursacht. Dies muss stattdessen in einer eigenen Zeile ausgeführt werden. Aber selbst dann ist eine Benutzereingabe erforderlich, um die Auslassungspunkte zu überspringen.
Unknow0059

3

myList.extend(['myString'] if condition else []) würde auch funktionieren, obwohl es mehr Arbeit ist als die anderen Lösungen.


0

Sie können so etwas tun:

myList.append('myString') if <condition> else False

oder

myList.append('myString') if <condition> else 0

False und 0 werden nicht an die Liste angehängt. Die Zeile muss nur etwas zurückgeben, wenn die Bedingung nicht erfüllt ist. Sie können die 0 oder False durch None oder eine leere Zeichenfolge oder eine beliebige Zeichenfolge ersetzen. Dies hat keine Auswirkungen auf die Liste.
Zachary Chiodini

Ich denke, mein damaliger Gedanke war im Fall eines Listenverständnisses. Meinen Kommentar gelöscht, Downvote war nicht ich. Ich nehme an, ein sauberer Weg wäre es, dies zu tun. myList.append('myString') if True else _Aber wenn Sie nichts zuweisen, spielt das keine Rolle. Ich bin besorgt darüber, dass diese Person versucht, ein Listenverständnis mit ähnlicher Logik zu erreichen.
Dave Liu

0

Ich würde dies nur tun, wenn ich optionale Elemente zu einer Liste hinzufügen möchte, die auf einer Bedingung basiert.

nums = [
        1,
        2,
        3 if <condition> else None,
        4,
       ]
nums = [i for i in nums if i is not None]

Dadurch wird der Wert nur durch "Keine" ersetzt, wenn die Bedingung nicht erfüllt ist. Später wird die Liste ohne die Werte "Keine" neu definiert. Auf diese Weise behalten sie ihren Index bei, wenn die Bedingung erfüllt ist

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.