Priorytet instrukcji logicznych NOT AND & OR w Pythonie

82

O ile wiem, w C i C ++ priorytetem dla NOT AND & OR jest NOT> AND> OR. Ale to nie wydaje się działać w podobny sposób w Pythonie. Próbowałem go poszukać w dokumentacji Pythona i nie udało mi się (chyba jestem trochę niecierpliwy). Czy ktoś może mi to wyjaśnić?

Akshar Gupta
źródło
2
Czy możesz podać przykład, w którym pierwszeństwo operatorów nie działa tak, jak myślisz, że działa?
dodgethesteamroller
nie jest większe niż i jest większe niż lub
CtrlAltF2

Odpowiedzi:

95

To NIE, AND, OR, od najwyższego do najniższego, zgodnie z dokumentacją dotyczącą pierwszeństwa operatorów

Oto pełna tabela priorytetów, od najniższego do najwyższego. Wiersz ma ten sam priorytet i łańcuchy od lewej do prawej

 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...}
Kyle Heuton
źródło
1
Zwróć uwagę, że **w przypisie podano pewne wyjątki, jeśli chodzi o pierwszeństwo przed operatorami arytmetycznymi.
Martijn Pieters
1
To dezorientuje matematyka we mnie: w arytmetyce powiedzielibyśmy, że ma ona pierwszeństwo przed operatorami arytmetycznymi. Po jego prawej stronie **operator nie ma pierwszeństwa przed operacjami arytmetycznymi, ale ma po lewej ... Na przykład 5*2**2 == 5*(2**2). Jednak słusznie to powiedzieć 2**-1 == 2**(-1).
PhilMacKay,
@PhilMacKay - może się wydawać, że np minus jest częścią intdosłowne, ale podczas analizowania go z astnią nie jest to przypadek - to UnaryOpz USuba 1jako argumentu. Prawdziwym powodem jest to, że nie ma innego sposobu, aby go przeanalizować. To 2**znaczy nie jest poprawnym lewym operandem dla binarnego minus. Tak więc „wyjątek priorytetu potęgowania”, ale „tylko po prawej”.
Tomasz Gandor
32

Możesz wykonać następujący test, aby ustalić pierwszeństwo andi or.

Najpierw spróbuj 0 and 0 or 1w konsoli Pythona

Jeśli orłączy się najpierw, spodziewalibyśmy się, że 0jako dane wyjściowe.

W mojej konsoli 1jest wyjście. Oznacza to and, że wiąże się jako pierwsze lub równe or(być może wyrażenia są oceniane od lewej do prawej).

Następnie spróbuj 1 or 0 and 0.

Jeśli ori andpowiążemy jednakowo z wbudowaną kolejnością oceny od lewej do prawej, powinniśmy otrzymać 0wynik.

W mojej konsoli 1jest wyjście. Następnie możemy stwierdzić, że andma wyższy priorytet niż or.

nr
źródło
3
Mówiąc dokładniej, wyrażenia są oceniane jako: ((0 and 0) or 1)i(1 or (0 and 0))
Conchylicultor
1
Jednak w drugim wyrażeniu (0 and 0)argument nigdy nie jest oceniany jako (exp1 or exp2)bezpośrednio zwracany, jeśli exp1jest True. Podobnie w pierwszym wyrażeniu and 0część nigdy nie jest oceniana jako exp1 and exp2bezpośrednio zwracana, jeśli exp1jest False.
Conchylicultor
5

Wśród operatorów logicznych pierwszeństwo, od najsłabszego do najsilniejszego, jest następujące:

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

Tam, gdzie operatory mają równy priorytet, ocena przebiega od lewej do prawej.

Oswald Wirt
źródło
Przepraszamy, Twój numer 2 jest poprawny technicznie, ale nadal bardzo mylący. Po pierwsze, dokument nie wydaje się zmieniać. Po drugie, twoja opinia nr 2 (sugerująca and& not xjest oceniana od lewej do prawej) jest technicznie równoważna z oficjalnym efektem, ale dzieje się tak po prostu dlatego, że gdy w "cond1, a nie cont2", Python musi domyślnie najpierw obliczyć cont2.
RayLuo
Dzięki @RayLuo, ale nie było to nawet poprawne technicznie . Umieszczałem znaczenie w nieprawidłowo wyrenderowanych liniach dzielących wiersze w tej tabeli. Patrząc na dzisiejszy dokument 2.7 ori andwydaje się, że znajduje się w tej samej komórce przy użyciu przeglądarki Firefox, ale nie Opery . Różnica w pierwszeństwie między ori andjest oczywista (np. 1 or 0 and 0Vs (1 or 0) and 0), że między andi not xnie tak bardzo z powodu, który podajesz. Naprawię swoją odpowiedź, aby odzwierciedlić to, co faktycznie mówi dokumentacja .
Oswald Wirt
2

Nie ma dobrego powodu, aby Python miał inną priorytetową sekwencję tych operatorów niż dobrze ugruntowana w (prawie) wszystkich innych językach programowania, w tym C / C ++.

Możesz go znaleźć w The Python Language Reference , część 6.16 - Pierwszeństwo operatorów, do pobrania (dla bieżącej wersji i spakowanej z całą inną standardową dokumentacją) z https://docs.python.org/3/download.html lub przeczytaj go online tutaj: 6.16. Pierwszeństwo operatorów .

Jednak w Pythonie jest jeszcze coś, co może zmylić: wynik operacji andi ormoże być inny niż operatory Trueor False- patrz 6.11 Operacje logiczne w tym samym dokumencie.

MarianD
źródło
1

Kilka prostych przykładów; zwróć uwagę na pierwszeństwo operatora (nie, i lub); stosuj nawiasy, aby ułatwić interpretację przez człowieka.

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

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

Podobnie:

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
Victoria Stuart
źródło