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ć?


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. if – else
 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
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.


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.


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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.