Ich versuche, eine Funktion zu erstellen, die mehrere Variablen mit einer Ganzzahl vergleicht und eine Zeichenfolge aus drei Buchstaben ausgibt. Ich habe mich gefragt, ob es eine Möglichkeit gibt, dies in Python zu übersetzen. Also sagen wir:
x = 0
y = 1
z = 3
mylist = []
if x or y or z == 0 :
mylist.append("c")
if x or y or z == 1 :
mylist.append("d")
if x or y or z == 2 :
mylist.append("e")
if x or y or z == 3 :
mylist.append("f")
das würde eine Liste von
["c", "d", "f"]
Ist so etwas möglich?
Sie verstehen nicht, wie boolesche Ausdrücke funktionieren; sie funktionieren nicht wie ein englischer Satz und vermuten, dass Sie hier über denselben Vergleich für alle Namen sprechen. Sie sind auf der Suche nach:
if x == 1 or y == 1 or z == 1:
x
und y
werden ansonsten alleine ausgewertet (False
wenn 0
, True
sonst).
Sie können das abkürzen, indem Sie einen Einschluss-Test gegen ein Tupel verwenden:
if 1 in (x, y, z):
oder noch besser:
if 1 in {x, y, z}:
unter Verwendung von a set
, um den Vorteil des Mitgliedschaftstests mit konstanten Kosten zu nutzen (in
benötigt eine feste Zeitspanne, unabhängig davon, wie der linke Operand lautet).
Wenn Sie oder
verwenden, betrachtet Python jede Seite des Operators als getrennte Ausdrücke. Der Ausdruck x oder y == 1
wird zunächst als boolescher Test für x
behandelt, und wenn dieser falsch ist, wird der Ausdruck y == 1
getestet.
Dies liegt an der Operatorpriorität. Der "oder"-Operator hat einen niedrigeren Vorrang als der "=="-Test, so dass letzterer zuerst ausgewertet wird.
Aber selbst wenn dies nicht der Fall wäre und der Ausdruck x oder y oder z == 1
stattdessen als (x oder y oder z) == 1
interpretiert würde, würde dies immer noch nicht das tun, was Sie erwarten.
x oder y oder z
würde zum ersten Argument ausgewertet, das 'wahr' ist, z.B. nicht False
, numerisch 0 oder leer (siehe boolean expressions für Details darüber, was Python als falsch in einem booleschen Kontext betrachtet).
Für die Werte x = 2; y = 1; z = 0
würde also x oder y oder z
zu 2
aufgelöst werden, da dies der erste wahrheitsgemäße Wert in den Argumenten ist. Dann wäre 2 == 1
False
, obwohl y == 1
True
wäre.
Dasselbe gilt für den umgekehrten Fall: Mehrere Werte gegen eine einzige Variable zu testen; x == 1 oder 2 oder 3
würde aus denselben Gründen fehlschlagen. Verwenden Sie x == 1 oder x == 2 oder x == 3
oder x in {1, 2, 3}
.
Ihr Problem lässt sich leichter mit einer Wörterbuchstruktur wie der folgenden lösen:
x = 0
y = 1
z = 3
d = {0: 'c', 1:'d', 2:'e', 3:'f'}
mylist = [d[k] for k in [x, y, z]]
Der direkte Weg, um "x oder y oder z == 0" zu schreiben, ist
if any(map((lambda value: value == 0), (x,y,z))):
pass # write your logic.
Aber ich glaube nicht, dass du das magst :) Und dieser Weg ist hässlich.
Der andere Weg (ein besserer) ist:
0 in (x, y, z)
BTW viele if
s könnten wie folgt geschrieben werden
my_cases = {
0: Mylist.append("c"),
1: Mylist.append("d")
# ..
}
for key in my_cases:
if key in (x,y,z):
my_cases[key]()
break