Priorität der logischen Anweisungen NOT AND & OR in Python


81

Soweit ich weiß, ist in C & C ++ die Prioritätssequenz für NOT AND & OR NOT> AND> OR. In Python scheint dies jedoch nicht ähnlich zu funktionieren. Ich habe versucht, in der Python-Dokumentation danach zu suchen, und bin gescheitert (ich glaube, ich bin etwas ungeduldig.). Kann jemand das für mich klären?


2
Können Sie ein Beispiel nennen, bei dem die Priorität des Operators nicht so funktioniert, wie Sie denken?
Dodgethesteamroller

nicht ist größer als und ist größer als oder
CtrlAltF2

Antworten:


93

Es ist NICHT UND UND ODER vom höchsten zum niedrigsten gemäß der Dokumentation zur Priorität des Bedieners

Hier ist die vollständige Prioritätstabelle, niedrigste Priorität bis höchste. Eine Zeile hat die gleiche Priorität und Ketten von links nach rechts

 0. :=
 1. lambda
 2. ifelse
 3. or
 4. and
 5. not x
 6. in, not in, is, is not, <, <=, >, >=, !=, ==
 7. |
 8. ^
 9. &
 10. <<, >>
 11. +, -
 12. *, @, /, //, %
 13. +x, -x, ~x
 14. **
 14. await x
 15. x[index], x[index:index], x(arguments...), x.attribute
 16. (expressions...), [expressions...], {key: value...}, {expressions...}

1
Beachten Sie, dass **in einer Fußnote einige Ausnahmen aufgeführt sind, wenn es um den Vorrang vor arithmetischen Operatoren geht.
Martijn Pieters

1
Das verwirrt den Mathematiker in mir: In der Arithmetik würden wir sagen, dass sie Vorrang vor arithmetischen Operatoren hat. Auf der rechten Seite hat der **Operator keinen Vorrang vor arithmetischen Operationen, aber auf der linken Seite ... Zum Beispiel 5*2**2 == 5*(2**2). Es ist jedoch richtig, das zu sagen 2**-1 == 2**(-1).
PhilMacKay

@PhilMacKay - es scheint, dass zB das Minus Teil des intLiteral ist, aber wenn man es mit analysiert, ist astes nicht der Fall - es ist UnaryOpmit USubund 1als Operand. Der wahre Grund ist, dass es keinen anderen Weg gibt, es zu analysieren. Dh 2**ist kein korrekter linker Operand für binäres Minus. Also "Exponentiationsprioritätsausnahme", aber "nur rechts".
Tomasz Gandor

32

Sie können den folgenden Test durchführen, um die Priorität von andund herauszufindenor .

Erster Versuch 0 and 0 or 1 in der Python-Konsole

Wenn orzuerst bindet, dann würden wir erwarten0 als Ausgabe .

In meiner Konsole 1ist die Ausgabe. Dies bedeutet, dass andentweder zuerst oder gleich orgebunden wird (möglicherweise werden Ausdrücke von links nach rechts ausgewertet).

Dann versuchen Sie es 1 or 0 and 0.

Wenn orund andbinden Sie gleichermaßen mit der eingebauten Bewertungsreihenfolge von links nach rechts, dann sollten wir 0als Ausgabe erhalten.

In meiner Konsole 1ist die Ausgabe. Dann können wir daraus schließen, dass dies andeine höhere Priorität hat als or.


3
Genauer ((0 and 0) or 1)(1 or (0 and 0))
Conchylicultor

1
Im zweiten Ausdruck wird das (0 and 0)jedoch niemals als (exp1 or exp2)direkt zurückgegeben ausgewertet, wenn dies der Fall exp1ist True. In ähnlicher Weise wird der and 0Teil im ersten Ausdruck niemals als exp1 and exp2direkt zurückgegeben ausgewertet, wenn dies der Fall exp1ist False.
Conchylicultor


4

Von den booleschen Operatoren hat die Priorität von der schwächsten zur stärksten folgende:

  1. or
  2. and
  3. not x
  4. is not;; not in

Bei gleichrangigen Operatoren erfolgt die Auswertung von links nach rechts.


Entschuldigung, Ihre Nummer 2 ist technisch korrekt, aber immer noch sehr irreführend. Erstens scheint sich das Dokument nicht zu ändern. Zweitens entspricht Ihre Meinung Nr. 2 (die and& not xvon links nach rechts bewertet & bewertet) technisch dem offiziellen Effekt, aber das liegt einfach daran, dass Python in "cond1 und nicht cont2" standardmäßig zuerst cont2 berechnen muss.
RayLuo

Danke @RayLuo, aber es war nicht einmal technisch korrekt. Ich habe den falsch gerenderten Zeilen, die die Zeilen in dieser Tabelle teilen, eine Bedeutung gegeben. Schauen Sie sich das 2.7-Dokument heute an or und andscheinen Sie mit Firefox in derselben Zelle zu sein, aber nicht mit Opera . Der Unterschied in der Priorität zwischen orund andist offensichtlich (z. B. 1 or 0 and 0vs (1 or 0) and 0), dass zwischen andund not xnicht so sehr aus dem von Ihnen angegebenen Grund. Ich werde meine Antwort reparieren, um zu reflektieren, was in der Dokumentation tatsächlich steht.
Oswald Wirt

2

Es gibt keinen guten Grund für Python, eine andere Prioritätssequenz dieser Operatoren als eine gut etablierte zu haben in (fast) allen anderen Programmiersprachen, einschließlich C / C ++.

Sie finden es möglicherweise in The Python Language Reference , Teil 6.16 - Operator Priority, herunterladbar (für die aktuelle Version und zusammen mit allen anderen Standarddokumentationen) unter https://docs.python.org/3/download.html oder lesen Sie es online hier: 6.16. Vorrang des Bedieners .

Aber es gibt noch etwas in Python , die Sie täuschen kann: Das Ergebnis von andund orBetreiber können unterschiedlich von Trueoder False- siehe 6.11 Boolesche Operationen im selben Dokument.


1

Einige einfache Beispiele; Beachten Sie die Priorität des Operators (nicht, und, oder). Klammern, um die Interpretierbarkeit des Menschen zu unterstützen.

a = 'apple'
b = 'banana'
c = 'carrots'

if c == 'carrots' and a == 'apple' and b == 'BELGIUM':
    print('True')
else:
    print('False')
# False

Ähnlich:

if b == 'banana'
True

if c == 'CANADA' and a == 'apple'
False

if c == 'CANADA' or a == 'apple'
True

if c == 'carrots' and a == 'apple' or b == 'BELGIUM'
True

# Note this one, which might surprise you:
if c == 'CANADA' and a == 'apple' or b == 'banana'
True

# ... it is the same as:
if (c == 'CANADA' and a == 'apple') or b == 'banana':
True

if c == 'CANADA' and (a == 'apple' or b == 'banana'):
False

if c == 'CANADA' and a == 'apple' or b == 'BELGIUM'
False

if c == 'CANADA' or a == 'apple' and b == 'banana'
True

if c == 'CANADA' or (a == 'apple' and b == 'banana')
True

if (c == 'carrots' and a == 'apple') or b == 'BELGIUM'
True

if c == 'carrots' and (a == 'apple' or b == 'BELGIUM')
True

if a == 'apple' and b == 'banana' or c == 'CANADA'
True

if (a == 'apple' and b == 'banana') or c == 'CANADA'
True

if a == 'apple' and (b == 'banana' or c == 'CANADA')
True

if a == 'apple' and (b == 'banana' and c == 'CANADA')
False

if a == 'apple' or (b == 'banana' and c == 'CANADA')
True
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.