Ich bin verwirrt, wann ich Boolesche vs bitweise Operatoren verwenden soll
and
vs.&
or
vs.|
Könnte mich jemand aufklären, wann ich die einzelnen Produkte verwende und wann sich die Verwendung übereinander auf meine Ergebnisse auswirkt?
Ich bin verwirrt, wann ich Boolesche vs bitweise Operatoren verwenden soll
and
vs. &
or
vs. |
Könnte mich jemand aufklären, wann ich die einzelnen Produkte verwende und wann sich die Verwendung übereinander auf meine Ergebnisse auswirkt?
Antworten:
Hier sind einige Richtlinien:
Das Kurzschlussverhalten ist in folgenden Ausdrücken nützlich:
if x is not None and x.foo == 42:
# ...
Dies würde mit dem bitweisen &
Operator nicht richtig funktionieren, da immer beide Seiten ausgewertet würden AttributeError: 'NoneType' object has no attribute 'foo'
. Wenn Sie den booleschen and
Operator verwenden, wird der zweite Ausdruck nicht ausgewertet, wenn der erste False ist. In ähnlicher Weise or
wird das zweite Argument nicht ausgewertet, wenn das erste True ist.
&
, |
, ^
werden die Operationen zu setzen.
True or "True"
ist in Ordnung (es wird der erste Wahrheitswert zurückgegeben), aber es True | "True"
wird eine Ausnahme ausgelöst .
0 == False
und 1 == True
beide wahr sind.
Theoretisch and
und or
kommen direkt aus der Booleschen Logik (und arbeiten daher mit zwei Booleschen Werten, um einen Booleschen Wert zu erzeugen), während &
und |
wenden den Booleschen Wert und / oder auf die einzelnen Bits von Ganzzahlen an. Hier gibt es viele Fragen, wie letztere genau funktionieren.
Hier sind praktische Unterschiede, die sich möglicherweise auf Ihre Ergebnisse auswirken:
and
und ein or
Kurzschluss, z. B. True or sys.exit(1)
wird nicht beendet, da für einen bestimmten Wert des ersten Operanden ( True or ...
, False and ...
) der zweite das Ergebnis nicht ändern würde und daher nicht ausgewertet werden muss. Aber |
und &
nicht kurzschließen - True | sys.exit(1)
wirft Sie aus der REPL.&
und |
sind reguläre Operatoren und können überladen werden, während and
und or
in die Sprache gefälscht werden (obwohl die spezielle Methode für Zwang zum Booleschen Wert Nebenwirkungen haben kann).
and
und or
geben Sie den Wert eines Operanden anstelle von True
oder zurück False
. Dies ändert nichts an der Bedeutung von Booleschen Ausdrücken in Bedingungen - 1 or True
ist 1
, ist aber auch 1
wahr. Es wurde jedoch einmal verwendet, um einen bedingten Operator zu emulieren ( cond ? true_val : false_val
in C-Syntax, true_val if cond else false_val
in Python). Für &
und |
hängt das Ergebnis Art, wie die Operanden die jeweiligen speziellen Methoden überlasten ( True & False
ist False
, 99 & 7
ist 3
, für Sätze es Gewerkschaften / Kreuzung ...).
Aber selbst wenn zB a_boolean & another_boolean
identisch funktionieren würde, wird die richtige Lösung verwendet and
- einfach weil and
und or
mit booleschem Ausdruck und Zustand verbunden sind, während &
und |
für Bit Twiddling stehen.
Hier ist ein weiterer Unterschied, der mich gerade eine Weile verwirrt hat: Weil &
(und andere bitweise Operatoren) eine höhere Priorität haben als and
(und andere boolesche Operatoren), werden die folgenden Ausdrücke mit unterschiedlichen Werten bewertet:
0 < 1 & 0 < 2
gegen
0 < 1 and 0 < 2
Das erste ergibt also, False
wie es äquivalent ist 0 < (1 & 0) < 2
, daher 0 < 0 < 2
daher 0 < 0 and 0 < 2
.
Wenn Sie versuchen, elementweise boolesche Operationen in auszuführen numpy
, ist die Antwort etwas anders. Sie können verwenden &
und |
elementweise Boolesche Operationen für, aber and
und or
wird Wert Fehler zurück.
Um auf der sicheren Seite zu sein, können Sie die numpy-Logikfunktionen verwenden .
np.array([True, False, True]) | np.array([True, False, False])
# array([ True, False, True], dtype=bool)
np.array([True, False, True]) or np.array([True, False, False])
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
np.logical_or(np.array([True, False, True]), np.array([True, False, False]))
# array([ True, False, True], dtype=bool)
Der Hinweis ist im Namen:
Während es möglich und manchmal wünschenswert ist (normalerweise aus Effizienzgründen), logische Operationen mit bitweisen Operatoren auszuführen, sollten Sie diese für solche Zwecke generell vermeiden, um subtile Fehler und unerwünschte Nebenwirkungen zu vermeiden.
Wenn Sie Bits bearbeiten müssen, sind die bitweisen Operatoren zweckgebunden. Das lustige Buch: Hackers Delight enthält einige coole und wirklich nützliche Beispiele dafür, was mit Bit-Twiddling erreicht werden kann.
Die allgemeine Regel besteht darin, den entsprechenden Operator für die vorhandenen Operanden zu verwenden. Verwenden boolean (logische) Operatoren mit boolean Operanden und bitweise Operatoren mit (größeren) integralen Operanden (Anmerkung: Falsch entsprechen 0 , und Wahre zu 1 ). Das einzige "knifflige" Szenario ist das Anwenden von Booleschen Operatoren auf nicht-Boolesche Operanden.
Nehmen wir ein einfaches Beispiel zu nehmen, wie beschrieben in [SO]: Python - Unterschiede zwischen ‚und‘ und ‚&‘ : 5 & 7
vs 5 and 7
.
Für das bitweise und ( & ) sind die Dinge ziemlich einfach:
5 = 0b101
7 = 0b111
-----------------
5 & 7 = 0b101 = 5
Für die logischen und , hier ist was [Python.Docs]: Boolesche Operationen besagt ( Schwerpunkt liegt bei mir):
(Beachten Sie, dass weder und noch oder den Wert und Typ einschränken, den sie auf False und True zurückgeben , sondern das zuletzt ausgewertete Argument zurückgeben .
Beispiel :
>>> 5 and 7
7
>>> 7 and 5
5
Gleiches gilt natürlich auch für | vs. oder .
Boolesche Operationen sind logische Operationen.
Bitweise Operationen sind Operationen an Binärbits.
Bitweise Operationen:
>>> k = 1
>>> z = 3
>>> k & z
1
>>> k | z
3
Die Operationen:
&
: 1, wenn beide Bits 1 sind, andernfalls 0|
: 1, wenn eines der Bits 1 ist, andernfalls 0^
: 1, wenn die Bits unterschiedlich sind, 0, wenn sie gleich sind~
': Flip jedes BitEinige der Verwendungen von bitweisen Operationen:
Boolesche Operationen:
>>> k = True
>>> z = False
>>> k & z # and
False
>>> k | z # or
True
>>>
Boolean 'und' vs. Bitwise '&':
Pseudocode / Python hat mir geholfen, den Unterschied zwischen diesen zu verstehen:
def boolAnd(A, B):
# boolean 'and' returns either A or B
if A == False:
return A
else:
return B
def bitwiseAnd(A , B):
# binary representation (e.g. 9 is '1001', 1 is '0001', etc.)
binA = binary(A)
binB = binary(B)
# perform boolean 'and' on each pair of binaries in (A, B)
# then return the result:
# equivalent to: return ''.join([x*y for (x,y) in zip(binA, binB)])
# assuming binA and binB are the same length
result = []
for i in range(len(binA)):
compar = boolAnd(binA[i], binB[i])
result.append(compar)
# we want to return a string of 1s and 0s, not a list
return ''.join(result)
werden normalerweise für bedingte Anweisungen verwendet. Zum Beispiel:
if a==2 and b>10:
# Do something ...
Das heißt, wenn beide Bedingungen ( a==2
und b>10
) gleichzeitig wahr sind, kann der bedingte Anweisungshauptteil ausgeführt werden.
werden zur Datenmanipulation und -extraktion verwendet. Wenn Sie beispielsweise die vier LSB (Least Significant Bits) einer Ganzzahl extrahieren möchten, können Sie Folgendes tun:
p & 0xF