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. Sozusagen:
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")
welches eine Liste von zurückgeben würde:
["c", "d", "f"]
Ist so etwas möglich?
python
if-statement
comparison
match
boolean-logic
user1877442
quelle
quelle
1
in (Tupel)any
/all
functions verwenden. Zum Beispiel:all([1, 2, 3, 4, False])
wird zurückgegeben Falseall([True, 1, 2, 3])
wird zurückgegeben Trueany([False, 0, 0, False])
wird zurückgegeben Falseany([False, 0, True, False])
wird True zurückgebenif x == 0 or 1:
, was natürlich ähnlich istif x or y == 0:
, aber für Neulinge dennoch etwas verwirrend sein könnte. Angesichts der schieren Lautstärke von "Warumx == 0 or 1
arbeite ich nicht ?" Fragen, ich würde diese Frage viel lieber als unser kanonisches doppeltes Ziel für diese Fragen verwenden.0
,0.0
oderFalse
. Sie können leicht falschen Code schreiben, der die "richtige" Antwort gibt.Antworten:
Sie verstehen falsch, wie boolesche Ausdrücke funktionieren. Sie funktionieren nicht wie ein englischer Satz und vermuten, dass Sie hier für alle Namen über denselben Vergleich sprechen. Du suchst nach:
x
undy
ansonsten auf ihre eigenen ausgewertet (False
wenn0
,True
anders).Sie können dies mit einem Eindämmungstest gegen ein Tupel verkürzen :
oder noch besser:
Verwenden von a
set
, um den Mitgliedschaftstest mit konstanten Kosten zu nutzen (in
dauert unabhängig vom linken Operanden eine feste Zeit).Wenn Sie verwenden
or
, sieht Python jede Seite des Operators als separate Ausdrücke. Der Ausdruckx or y == 1
wird zuerst als boolescher Test behandelt.x
Wenn dies falsch ist, wird der Ausdrucky == 1
getestet.Dies liegt an der Priorität des Bedieners . Der
or
Bediener hat eine niedrigere Priorität als der==
Test, daher wird letzterer zuerst bewertet .Selbst wenn dies nicht der Fall wäre und der Ausdruck
x or y or z == 1
tatsächlich so interpretiert(x or y or z) == 1
würde, würde dies immer noch nicht das tun, was Sie von ihm erwarten.x or y or z
würde bis zum ersten Argument auswerten, das 'wahr' ist, z. B. nichtFalse
, numerisch 0 oder leer (siehe boolesche Ausdrücke für Details darüber, was Python in einem booleschen Kontext als falsch betrachtet).Also für die Werte
x = 2; y = 1; z = 0
,x or y or z
würde lösen zu2
, denn das ist der erste echte ähnliche Wert in den Argumenten ist. Dann2 == 1
wäre esFalse
, obwohl es soy == 1
wäreTrue
.Gleiches würde für die Umkehrung gelten; Testen mehrerer Werte gegen eine einzelne Variable;
x == 1 or 2 or 3
würde aus den gleichen Gründen scheitern. Verwenden Siex == 1 or x == 2 or x == 3
oderx in {1, 2, 3}
.quelle
set
Version entscheiden. Tupel sind sehr billig zu erstellen und zu wiederholen. Zumindest auf meinem Computer sind Tupel schneller als Sätze, solange die Größe des Tupels etwa 4-8 Elemente beträgt. Wenn Sie mehr scannen müssen, verwenden Sie ein Set. Wenn Sie jedoch nach einem Objekt mit 2 bis 4 Möglichkeiten suchen, ist ein Tupel immer noch schneller! Wenn Sie für die wahrscheinlichste Fall anordnen können in dem Tupel ersten sein, ist der Gewinn noch größer: (mein Test:timeit.timeit('0 in {seq}'.format(seq=tuple(range(9, -1, -1))))
)set
für diesen Test ist keine Ersparnis, es sei denn, der Inhalt desset
Literal ist auch ein Literal, oder?if 1 in {x, y, z}:
kann das nicht cachenset
, weilx
,y
undz
könnte sich ändern, so braucht entweder Lösung ein bauentuple
oderset
von Grund auf neu, und ich vermute , was Einsparungen Nachschlag Sie erhalten könnten , wenn für die Mitgliedschaft Überprüfung durch mehr überschwemmt werden würdeset
Erstellungszeit.in [...]
oderin {...}
) funktioniert nur, wenn der Inhalt der Liste oder des Satzes auch unveränderliche Literale sind.Ihr Problem lässt sich leichter mit einer Wörterbuchstruktur wie der folgenden beheben:
quelle
d = "cdef"
was zuMyList = ["cdef"[k] for k in [x, y, z]]
map(lambda i: 'cdef'[i], [x, y, z])
[x, y, z]
Wie von Martijn Pieters angegeben, ist das richtige und schnellste Format:
Mit seinem Rat hätten Sie jetzt separate if-Anweisungen, damit Python jede Anweisung lesen kann, unabhängig davon, ob die ersteren waren
True
oder nichtFalse
. Sowie:Dies wird funktionieren, aber wenn Sie mit der Verwendung von Wörterbüchern vertraut sind (siehe, was ich dort getan habe), können Sie dies bereinigen, indem Sie ein erstes Wörterbuch erstellen, in dem die Zahlen den gewünschten Buchstaben zugeordnet sind, und dann einfach eine for-Schleife verwenden:
quelle
Der direkte Weg zu schreiben
x or y or z == 0
istAber ich glaube nicht, dass es dir gefällt. :) Und dieser Weg ist hässlich.
Der andere Weg (ein besserer) ist:
Übrigens
if
könnten viele s so geschrieben werdenquelle
dict
anstelle eines Schlüssels erhalten Sie Fehler, da der Rückgabewert von.append
isNone
ist und der Aufruf einNone
ergibtAttributeError
. Im Allgemeinen stimme ich dieser Methode jedoch zu.filter
wäre besser alsmap
, da es nur Fälle zurückgibt, in denen Lambda als wahr ausgewertet wirdany(v == 0 for v in (x, y, z))
Wenn Sie sehr, sehr faul sind, können Sie die Werte in ein Array einfügen. Sowie
Sie können die Zahlen und Buchstaben auch in ein Wörterbuch einfügen und dies tun, aber dies ist wahrscheinlich VIEL komplizierter als nur if-Anweisungen. Das bekommst du, wenn du versuchst, besonders faul zu sein :)
Noch eine Sache, deine
wird kompiliert, aber nicht so, wie Sie es möchten. Wenn Sie einfach eine Variable in eine if-Anweisung einfügen (Beispiel)
Das Programm prüft, ob die Variable nicht null ist. Eine andere Möglichkeit, die obige Aussage zu schreiben (was sinnvoller ist), ist
Bool ist eine in Python eingebaute Funktion, die im Grunde den Befehl zum Überprüfen einer booleschen Anweisung ausführt (Wenn Sie nicht wissen, was das ist, versuchen Sie es gerade in Ihrer if-Anweisung :))
Ein anderer fauler Weg, den ich gefunden habe, ist:
quelle
list
ist ein Python eingebaut; Verwenden Sie stattdessen einen anderen Namen, wiexyz
zum Beispiel. Warum erstellen Sie die Liste in vier Schritten, wenn Sie einen ausführen können, dhxyz = [x, y, z]
? Verwenden Sie keine parallelen Listen, sondern ein Diktat. Alles in allem ist diese Lösung viel komplizierter als die von ThatGuyRussell . Warum nicht auch für den letzten Teil ein Verständnis machen, dhany(v == 0 for v in (x, y, z))
? Auch Arrays sind etwas anderes in Python.Um zu überprüfen, ob ein Wert in einer Reihe von Variablen enthalten ist, können Sie die eingebauten Module
itertools
und verwendenoperator
.Zum Beispiel:
Importe:
Variablen deklarieren:
Erstellen Sie eine Zuordnung von Werten (in der Reihenfolge, die Sie überprüfen möchten):
Verwenden Sie
itertools
diese Option , um die Wiederholung der Variablen zu ermöglichen:Verwenden Sie
map
abschließend die Funktion, um einen Iterator zu erstellen:Verwenden Sie dann bei der Überprüfung der Werte (in der ursprünglichen Reihenfolge)
next()
:usw...
Dies hat einen Vorteil gegenüber der ,
lambda x: x in (variables)
weiloperator
ein eingebautes Modul und ist schneller und effizienter als die Verwendung ,lambda
die eine individuelle Vor-Ort - Funktion zu erstellen hat.Eine weitere Option zum Überprüfen, ob eine Liste einen Wert ungleich Null (oder Falsch) enthält:
Äquivalent:
quelle
Set ist hier der gute Ansatz, weil es die Variablen ordnet, was hier Ihr Ziel zu sein scheint.
{z,y,x}
ist{0,1,3}
unabhängig von der Reihenfolge der Parameter.Auf diese Weise ist die gesamte Lösung O (n).
quelle
Alle hier
if 1 in {x,y,z}
gegebenen hervorragenden Antworten konzentrieren sich auf die spezifischen Anforderungen des Originalplakats und auf die von Martijn Pieters vorgeschlagene Lösung.Was sie ignorieren, ist die umfassendere Implikation der Frage:
Wie teste ich eine Variable gegen mehrere Werte?
Die bereitgestellte Lösung funktioniert nicht für Teiltreffer, wenn beispielsweise Zeichenfolgen verwendet werden:
Testen Sie, ob die Zeichenfolge "Wild" mehrere Werte enthält
oder
In diesem Szenario ist es am einfachsten, in eine Zeichenfolge zu konvertieren
Es ist jedoch zu beachten
@codeforester
, dass , wie erwähnt , bei dieser Methode Wortgrenzen verloren gehen, wie in:Die 3 Buchstaben
rot
sind in der Liste in Kombination vorhanden, jedoch nicht als einzelnes Wort. Das Testen auf "rot" würde fehlschlagen, aber wenn eines der Listenelemente "rot in hell" wäre, würde dies ebenfalls fehlschlagen.Das Ergebnis ist, seien Sie vorsichtig mit Ihren Suchkriterien, wenn Sie diese Methode verwenden, und beachten Sie, dass diese Einschränkung vorliegt.
quelle
Ich denke, das wird besser damit umgehen:
Ausgabe:
quelle
Wenn Sie if verwenden möchten, sind die folgenden Anweisungen eine andere Lösung:
quelle
quelle
Dieser Code kann hilfreich sein
quelle
Sie können die unten gezeigte Methode ausprobieren. Bei dieser Methode haben Sie die Freiheit, die Anzahl der Variablen anzugeben / einzugeben, die Sie eingeben möchten.
quelle
Einzeilige Lösung:
Oder:
quelle
Möglicherweise benötigen Sie eine direkte Formel für die gesetzten Ausgangsbits.
Lassen Sie uns auf Bits abbilden:
'c':1 'd':0xb10 'e':0xb100 'f':0xb1000
Beziehung von isc (ist 'c'):
Verwenden Sie die mathematische Formel https://youtu.be/KAdKCgBGK0k?list=PLnI9xbPdZUAmUL8htSl6vToPQRRN3hhFp&t=315
[c]:
(xyz=0 and isc=1) or (((xyz=0 and isc=1) or (isc=0)) and (isc=0))
[d]:
((x-1)(y-1)(z-1)=0 and isc=2) or (((xyz=0 and isd=2) or (isc=0)) and (isc=0))
...
Verbinden Sie diese Formeln mit folgender Logik:
and
ist die Summe der Gleichungsquadrateor
ist das Produkt von Gleichungenund Sie haben eine Gesamtgleichung Express Summe und Sie haben eine Gesamtformel der Summe
dann ist Summe & 1 c, Summe & 2 ist d, Summe & 4 ist e, Summe & 5 ist f
Danach können Sie ein vordefiniertes Array bilden, in dem der Index der Zeichenfolgenelemente der fertigen Zeichenfolge entspricht.
array[sum]
gibt Ihnen die Zeichenfolge.quelle
Es kann leicht gemacht werden als
quelle
Die mnemonischste Art, Ihren Pseudocode in Python darzustellen, wäre:
quelle
if any(v >= 42 for v in (x, y, z)):
. B. ). Und Leistung aller drei Methoden (2 in {x,y,z}
,2 in (x,y,z)
,any(_v == 2 for _v in (x,y,z))
) in CPython3.6 fast das gleiche zu sein scheint (siehe Gist )So testen Sie mehrere Variablen mit einem einzigen Wert:
if 1 in {a,b,c}:
So testen Sie mehrere Werte mit einer Variablen:
if a in {1, 2, 3}:
quelle
Sieht so aus, als würden Sie eine Art Caesar-Chiffre bauen.
Ein viel allgemeinerer Ansatz ist folgender:
Ausgänge
Sie sind sich nicht sicher, ob es sich um einen gewünschten Nebeneffekt Ihres Codes handelt, aber die Reihenfolge Ihrer Ausgabe wird immer sortiert.
Wenn Sie dies wünschen, kann die letzte Zeile geändert werden in:
quelle
Sie können das Wörterbuch verwenden:
quelle
Versuchen Sie diese Lösung ohne Diktat:
und gibt:
quelle
Das wird dir helfen.
quelle
Sie können dies vereinen
in einer Variablen.
Ändern Sie unsere Bedingungen wie folgt:
Ausgabe:
quelle
Problem
Während das Muster zum Testen mehrerer Werte
ist sehr gut lesbar und funktioniert in vielen Situationen, es gibt eine Falle:
Aber wir wollen haben
Lösung
Eine Verallgemeinerung des vorherigen Ausdrucks basiert auf der Antwort von ytpillai :
was geschrieben werden kann als
Obwohl dieser Ausdruck das richtige Ergebnis zurückgibt, ist er nicht so lesbar wie der erste Ausdruck :-(
quelle