Wie erhält man das logische xor von zwei Variablen in Python?
Zum Beispiel habe ich zwei Variablen, von denen ich erwarte, dass sie Zeichenfolgen sind. Ich möchte testen, ob nur einer von ihnen einen True-Wert enthält (nicht None oder die leere Zeichenfolge):
str1 = raw_input("Enter string one:")
str2 = raw_input("Enter string two:")
if logical_xor(str1, str2):
print "ok"
else:
print "bad"
Der ^
Operator scheint bitweise zu sein und nicht für alle Objekte definiert zu sein:
>>> 1 ^ 1
0
>>> 2 ^ 1
3
>>> "abc" ^ ""
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for ^: 'str' and 'str'
python
logical-operators
Zach Hirsch
quelle
quelle
a xor a
definiert als(a and not b) or (not a and b)
, und soa xor b
, wenna
undb
Zeichenketten sind, oder alle anderen Arten sollten unabhängig ergeben(a and not b) or (not a and b)
Ausbeuten.Antworten:
Wenn Sie die Eingaben bereits auf Boolesche Werte normalisieren, ist! = Xor.
quelle
bool(a) is not bool(b)
stattdessen sein?Sie können immer die Definition von xor verwenden, um sie aus anderen logischen Operationen zu berechnen:
Aber das ist mir etwas zu ausführlich und auf den ersten Blick nicht besonders klar. Ein anderer Weg, dies zu tun, ist:
Der xor-Operator für zwei Boolesche Werte ist logisch xor (im Gegensatz zu Ints, wo er bitweise ist). Was Sinn macht, da
bool
es sich nur um eine Unterklasse von handeltint
, aber implementiert wird, um nur die Werte0
und zu haben1
. Und logisches xor entspricht bitweisem xor, wenn die Domäne auf0
und beschränkt ist1
.Die
logical_xor
Funktion würde also wie folgt implementiert:Dank an Nick Coghlan auf der Python-3000-Mailingliste .
quelle
(not b and a) or (not a and b)
so setzen, damit die Zeichenfolge zurückgegeben wird, falls vorhanden, was wie die pythonische Funktionsweise der Funktion erscheint.Bitweise exklusiv - oder ist bereits in Python im
operator
Modul integriert (identisch mit dem^
Operator):quelle
xor(1, 2)
kehrt zurück3
. Aus der Dokumentzeichenfolge:xor(a, b) -- Same as a ^ b.
Denken Sie daran, dass alles, was aus importiertoperator
wird, nur eine funktionale Form eines vorhandenen integrierten Infix-Operators ist.bool
Typ wird überladen__xor__
, um Boolesche Werte zurückzugeben. Es wird gut funktionieren, aber es ist übertrieben, wennbool(a) ^ bool(b)
es genau das Gleiche tut.^
Operator ruft__xor__
intern auf.bool
Typ die__xor__
Methode speziell^
implementiert , weil er sie aufruft . Der Punkt ist, dass gutbool(a) ^ bool(b)
funktioniert, es besteht keine Notwendigkeit, die zu verwendenoperator.xor()
Funktion hier nicht verwendet werden.Wie Zach erklärte, können Sie verwenden:
Ich persönlich bevorzuge einen etwas anderen Dialekt:
Dieser Dialekt ist inspiriert von einer logischen Diagrammsprache, die ich in der Schule gelernt habe, in der "ODER" durch ein Kästchen mit
≥1
(größer oder gleich 1) und "XOR" durch ein Kästchen mit=1
.Dies hat den Vorteil, dass exklusive oder mehrere Operanden korrekt implementiert werden.
quelle
(((((True + True)==1)+False)==1)+True)==1
. Die hier gegebene Antwort verallgemeinert sich vollständig auf mehrere Operanden.True + True + False + True
, Sie tun bekommen3
, undTrue + True + False + True == 3
gibt zurück ,True
währendTrue + True + False + True == 1
zurück gibtFalse
. Mit anderen Worten, die Antwort hier verallgemeinert sich nicht richtig. Dazu müssen Sie zusätzliche Arbeit leisten. InzwischenTrue ^ True ^ False ^ True
funktioniert ein einfaches wie erwartet.True
ein Multi-Arity-XOR ist. Dies ist eine andere Operation als zum BeispielA XOR B XOR ... XOR Z
. Mit anderen Worten, wenn Sie die additionsbasierte Version verwenden möchtenTrue + True + False + True
, sollten Sie nach dem Senden der Operanden in erwarten, dass das ErgebnisFalse
mehr als eines davon istTrue
, was funktioniert, wenn die Bedingung dies überprüft== 1
.or
:A or B
: Erträge ,A
wennbool(A)
istTrue
, sonst kehrtB
and
:A and B
: Erträge ,A
wennbool(A)
istFalse
, sonst kehrtB
Um den größten Teil dieser Denkweise beizubehalten, wäre meine logische xor Definition:
Auf diese Weise können sie zurückkehren
a
,b
oderFalse
:quelle
and
undor
nicht logischen Wert zurück.'foo' and 'bar'
kehrt zurück'bar'
...xor
Implementierung liefert, die mit dem integriertenand
und übereinstimmtor
. Natürlich sind sie in praktischen Situationenbool(a) ^ bool(b)
oder sogara ^ b
(wenna
undb
wie bekanntbool
) prägnanter.Ich habe verschiedene Ansätze getestet und
not a != (not b)
schien der schnellste zu sein.Hier sind einige Tests
Bearbeiten: In den obigen Beispielen 1 und 3 fehlen Klammern, sodass das Ergebnis falsch ist. Neue Ergebnisse +
truth()
Funktion wie von ShadowRanger vorgeschlagen.quelle
from operator import truth
am oberen Rand des Moduls testentruth(a) != truth(b)
.bool
ein Konstruktor Wesen hat eine Menge von unvermeidbaren Overhead an der C - Ebene (es muss Argumente als äquivalent akzeptiert*args, **kwargs
die und analysierttuple
unddict
sie zu extrahieren), wobeitruth
(eine Funktion ist) kann einen optimierten Pfad verwenden, der nicht erfordert entweder eintuple
oder adict
und läuft in etwa der Hälfte der Zeit vonbool
basierten Lösungen (aber immer noch länger alsnot
basierte Lösungen).Belohnungsthread:
Anoder Idee ... Versuchen Sie einfach den (möglicherweise) pythonischen Ausdruck «ist nicht», um das Verhalten des logischen «xor» zu erhalten.
Die Wahrheitstabelle wäre:
Und für Ihre Beispielzeichenfolge:
Jedoch; Wie oben angegeben, hängt es vom tatsächlichen Verhalten ab, das Sie bei einigen Saiten herausziehen möchten, da Saiten keine Boleans sind ... und noch mehr: Wenn Sie in Python eintauchen, finden Sie "The Peculiar Nature of". und "und" oder "» http://www.diveintopython.net/power_of_introspection/and_or.html
Entschuldigung, mein geschriebenes Englisch, es ist nicht meine geborene Sprache.
Grüße.
quelle
Python hat einen bitweisen Exklusiv-ODER-Operator
^
:Sie können es verwenden, indem Sie die Eingaben in Boolesche Werte konvertieren, bevor Sie xor (
^
) anwenden :(Bearbeitet - danke Arel)
quelle
^
es sich um ein bitweises xor handelt (nicht um ein logisches xor wie die gestellte Frage).bool(2) ^ bool(3)
gibt eine andere Antwort alsbool(2 ^ 3)
.a ^ b
ist polymorph. Wenna
undb
sindbool
Instanzen, wird das Ergebnisbool
als gut. Dieses Verhalten kann kaum als "bitweises" xor bezeichnet werden.^
als bitweise definiert , obwohl es ein interessanter Punkt ist, für den Typenbool
undint
Typen beibehalten werden. Hinweis:True ^ 2
zeigt3
, wie es tatsächlich bitweise ist.bool ^ int
Fall ist, allesint
zuerst zu besetzen . Dennoch hat Python eingebauten dem^
Operator für viele Bits inint
und für die ein Bit in a dargestelltbool
, so sind beide bitweise , aber die bitweise xor für ein einzelnes Bit nur ist die logische xor für booleans.xor
, dass er sich aus technischer Sicht instinktiv wie eine mathematische Kraft anfühlt, dh2^3 = pow(2,3)
ich kommentiere immer explizit, um Verwirrung zu vermeiden.Da ich die einfache Variante von xor nicht sehe, die variable Argumente verwendet und nur die Wahrheitswerte True oder False verwendet, werde ich sie hier nur für jedermann verwenden. Es ist, wie von anderen bemerkt, hübsch (um nicht sehr zu sagen) unkompliziert.
Auch die Verwendung ist unkompliziert:
Da dies das verallgemeinerte n-ary logische XOR ist, ist sein Wahrheitswert immer dann True, wenn die Anzahl der True-Operanden ungerade ist (und nicht nur, wenn genau einer True ist, dies ist nur ein Fall, in dem n-ary XOR True ist).
Wenn Sie also nach einem n-ary-Prädikat suchen, das nur dann True ist, wenn genau einer seiner Operanden ist, möchten Sie möglicherweise Folgendes verwenden:
quelle
(bool(False) is False) == True
. Sie können nurFalse
auf diesen Zeilen verwenden.Exklusiv Oder ist wie folgt definiert
quelle
and
undor
Kurzschluss machen. Jedexor
Implementierung kann nicht kurzschließen, daher besteht bereits eine Diskrepanz. Daher gibt es keinen Grund, derxor
wieand
+or
do funktionieren sollte .Manchmal arbeite ich mit 1 und 0 anstelle von booleschen True- und False-Werten. In diesem Fall kann xor definiert werden als
welches die folgende Wahrheitstabelle hat:
quelle
Ich weiß, dass dies spät ist, aber ich hatte einen Gedanken und es könnte sich lohnen, nur zur Dokumentation. Vielleicht würde das funktionieren:
np.abs(x-y)
Die Idee ist dasquelle
Einfach, leicht zu verstehen:
Wenn Sie nach einer exklusiven Auswahl suchen, kann diese auf mehrere Argumente erweitert werden:
quelle
sum(map(bool, y)) % 2 == 1
Wie wäre es damit?
wird geben,
a
wennb
falsch ist,wird geben,
b
wenna
falsch ist,wird geben
False
andersOder mit dem ternären Ausdruck Python 2.5+:
quelle
Einige der hier vorgeschlagenen Implementierungen führen in einigen Fällen zu einer wiederholten Bewertung der Operanden, was zu unbeabsichtigten Nebenwirkungen führen kann und daher vermieden werden muss.
Das heißt, eine
xor
Implementierung, die entweder zurückgibtTrue
oderFalse
ziemlich einfach ist; Eine, die nach Möglichkeit einen der Operanden zurückgibt, ist viel schwieriger, da kein Konsens darüber besteht, welcher Operand der ausgewählte sein soll, insbesondere wenn mehr als zwei Operanden vorhanden sind. Zum Beispiel solltexor(None, -1, [], True)
zurückkehrenNone
,[]
oderFalse
? Ich wette, jede Antwort erscheint einigen Leuten als die intuitivste.Für das True- oder das False-Ergebnis gibt es bis zu fünf mögliche Optionen: Rückgabe des ersten Operanden (wenn er mit dem Endergebnis im Wert übereinstimmt, sonst Boolescher Wert), Rückgabe der ersten Übereinstimmung (wenn mindestens einer vorhanden ist, sonst Boolescher Wert), letzten Operanden zurückgeben (wenn ... sonst ...), letzte Übereinstimmung zurückgeben (wenn ... sonst ...) oder immer boolesch zurückgeben. Insgesamt sind das 5 ** 2 = 25 Geschmacksrichtungen
xor
.quelle
Viele Leute, einschließlich mir, benötigen eine
xor
Funktion, die sich wie eine xor-Schaltung mit n Eingängen verhält, wobei n variabel ist. (Siehe https://en.wikipedia.org/wiki/XOR_gate ). Die folgende einfache Funktion implementiert dies.Beispiel-E / A folgt:
quelle
So erhalten Sie das logische xor von zwei oder mehr Variablen in Python:
^
oderoperator.xor
)Zum Beispiel,
Wenn Sie die Eingaben in Boolesche Werte konvertieren, wird bitweises xor zu logischem xor.
Beachten Sie, dass die akzeptierte Antwort falsch ist: Sie
!=
ist aufgrund der Subtilität der Operatorverkettung nicht mit xor in Python identisch .Zum Beispiel ist das xor der drei folgenden Werte falsch, wenn
!=
:(PS Ich habe versucht, die akzeptierte Antwort so zu bearbeiten, dass sie diese Warnung enthält, aber meine Änderung wurde abgelehnt.)
quelle
Es ist einfach, wenn Sie wissen, was XOR tut:
quelle
Dies erhält das logische exklusive XOR für zwei (oder mehr) Variablen
Das erste Problem bei diesem Setup besteht darin, dass es höchstwahrscheinlich die gesamte Liste zweimal durchläuft und mindestens eines der Elemente mindestens zweimal überprüft. Dies kann das Codeverständnis verbessern, führt jedoch nicht zu einer Geschwindigkeitssteigerung (die sich je nach Anwendungsfall vernachlässigbar unterscheiden kann).
Das zweite Problem bei diesem Setup besteht darin, dass unabhängig von der Anzahl der Variablen die Exklusivität überprüft wird. Dies kann zunächst als Merkmal angesehen werden, aber das erste Problem wird mit zunehmender Anzahl von Variablen (falls dies jemals der Fall ist) viel bedeutender.
quelle
Xor ist
^
in Python. Es gibt zurück:__xor__
.Wenn Sie sie ohnehin für Zeichenfolgen verwenden möchten,
bool
wird Ihre Operation durch Eingießen eindeutig (Sie könnten auch meinenset(str1) ^ set(str2)
).quelle
XOR ist implementiert in
operator.xor
.quelle
So würde ich jede Wahrheitstabelle codieren. Insbesondere für xor haben wir:
Schauen Sie sich einfach die T-Werte in der Antwortspalte an und setzen Sie alle wahren Fälle mit logischem oder zusammen. Diese Wahrheitstabelle kann also in Fall 2 oder 3 erstellt werden.
quelle
Wir können xor von zwei Variablen leicht finden, indem wir verwenden:
Beispiel:
quelle
xor("hey", "there")
>>> Stimmt, aber das wollen wir nicht