Menu

and, or, not w Pythonie: operatory logiczne, skracanie i truthiness

Jak działają operatory and, or i not w Pythonie: tabele prawdy, wartości truthy i falsy, obliczanie skrócone, dlaczego and/or zwracają jeden z operandów, priorytety oraz and/or kontra & i |.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Trzy słowa zamiast symboli

Operatory logiczne w Pythonie to angielskie słowa and, or i not. Inne języki zapisują je jako &&, || i !. W Pythonie && i || dają SyntaxError, a ! pojawia się tylko jako część != ("różne od").

Dla True i False reguły są takie, jakich się spodziewasz:

aba and ba or bnot a
TrueTrueTrueTrueFalse
TrueFalseFalseTrueFalse
FalseTrueFalseTrueTrue
FalseFalseFalseFalseTrue

and wymaga, żeby obie strony były prawdziwe. or wymaga przynajmniej jednej. not przyjmuje jedną wartość i ją odwraca.

W prawdziwym kodzie po obu stronach stoją zwykle porównania, a wynik trafia do if albo while:

Wynik:

eligible
standard ticket

Tyle wystarczy do większości warunków. Reszta tej strony opisuje, co operatory robią z wartościami innymi niż True i False, oraz reguły, które decydują, która strona wyrażenia zostanie wykonana.

Wartości truthy i falsy

and, or i not przyjmują dowolne wartości, nie tylko logiczne. Python decyduje, czy wartość liczy się jako prawda, na podstawie jej truthiness. Te wartości są falsy:

  • False i None
  • zero dowolnego typu liczbowego: 0, 0.0
  • puste kontenery i napisy: "", [], (), {}, set(), range(0)

Wszystko inne jest truthy, także "0", "False", [0] i -1. To, jak Python klasyfikuje wartość, sprawdzisz przez bool():

Wynik:

0 False
1 True
-1 True
'' False
'0' True
[] False
[0] True
None False
0.0 False

Napis "0" jest truthy, bo to niepusty napis. To łapie osoby, które wczytują liczby z wejścia i sprawdzają je przed konwersją. Strona o liczbach i wartościach logicznych wyjaśnia, jak bool ma się do int.

and i or zwracają operand

Tu Python różni się od większości języków. and i or nie tworzą nowego True ani False. Zwracają jedną z dwóch wartości, które im przekazujesz:

  • x or y zwraca x, jeśli x jest truthy, a w przeciwnym razie zwraca y.
  • x and y zwraca x, jeśli x jest falsy, a w przeciwnym razie zwraca y.

Gdy oba operandy są wartościami logicznymi, "zwróć operand" i "zwróć wartość logiczną" to to samo. Dlatego różnica pozostaje niezauważona, dopóki nie wmieszasz innych typów.

Wyjątkiem jest not: zawsze zwraca True albo False.

Jeśli potrzebujesz prawdziwej wartości logicznej z wyrażenia and/or, na przykład żeby ją zapisać albo zwrócić z funkcji, która obiecuje bool, opakuj je w bool():

Obliczanie skrócone (short-circuit)

Python oblicza and i or od lewej do prawej i zatrzymuje się, gdy tylko odpowiedź jest znana:

  • and zatrzymuje się na pierwszej wartości falsy, bo nic dalej nie sprawi, że całe wyrażenie będzie prawdziwe.
  • or zatrzymuje się na pierwszej wartości truthy, bo nic dalej nie sprawi, że całe wyrażenie będzie fałszywe.

Pominięta strona w ogóle się nie wykonuje. Zobaczysz to na funkcjach, które wypisują komunikat przy wywołaniu:

Wynik:

and:
  checking A
False
or:
  checking A
True

W żadnym z przypadków B nie jest sprawdzane. Dzięki obliczaniu skróconemu warunki ochronne są bezpieczne. Druga połowa każdego warunku poniżej sama by się wysypała, ale uruchamia się dopiero wtedy, gdy pierwsza połowa wykluczy zły przypadek:

Tani albo ochronny test stawiaj na początku. Odwrócona kolejność, user.startswith("admin") and user is not None, zgłasza AttributeError, gdy user to None.

Wzorce oparte na or i and

Ponieważ or zwraca swój pierwszy operand truthy, daje jednolinijkową wartość domyślną:

Wynik:

Hello, Ada!
Hello, guest!
Hello, guest!

Haczyk polega na tym, że or zastępuje każdą wartość falsy, a nie tylko None. Jeśli 0, "" albo [] to poprawne dane wejściowe, or je wyrzuci:

Używaj x if x is not None else default, gdy zero albo pusta wartość jest poprawna. To wyrażenie warunkowe opisuje strona o if/else.

and ma odpowiadający wzorzec: "użyj tej wartości tylko wtedy, gdy pierwsza jest ustawiona". Jest rzadszy i często czytelniej wygląda jako if, więc sięgaj po niego oszczędnie:

Priorytety: najpierw not, potem and, potem or

Gdy wyrażenie łączy wszystkie trzy, Python stosuje najpierw not, potem and, a na końcu or. Porównania, takie jak ==, < i in, są stosowane przed każdym z nich.

a or b and c i (a or b) and c dają różne odpowiedzi dla tych samych wartości, więc mieszany warunek powinien mieć nawiasy, nawet gdy domyślna kolejność akurat jest właściwa. Nic nie kosztują, a następna osoba czytająca kod nie musi się zastanawiać.

and/or kontra &/|

& i | wyglądają podobnie do and i or i czasem dają tę samą odpowiedź, ale to różne operatory.

  • and / or sprawdzają truthiness, obliczają się w sposób skrócony i zwracają jeden z operandów.
  • & / | to operatory bitowe. Na liczbach całkowitych łączą bity obu liczb. Na zbiorach oznaczają część wspólną i sumę. Na True i False zwracają wartość logiczną. Nigdy nie skracają obliczeń: obie strony są zawsze obliczane.

Operatory bitowe mają też wyższy priorytet niż porównania, przez co warunek zapisany z & staje się czymś zupełnie innym:

1 & y to 1 & 5, czyli 1, więc środkowa linia staje się łańcuchem 5 > 1 > 1, a 1 > 1 jest fałszem. W zwykłym kodzie Pythona do warunków używaj and, or i not.

Jedyne miejsce, gdzie &, | i ~ są właściwe w warunkach, to NumPy i pandas. Tablica przechowuje wiele wartości, więc nie ma jednej wartości logicznej, a and zgłasza ValueError: The truth value of an array ... is ambiguous. Biblioteki przeciążają & i |, żeby działały element po elemencie. Dlatego filtry w pandas wyglądają jak df[(df.age > 18) & (df.country == "CA")], z nawiasami wokół każdego porównania z powodu opisanych wyżej priorytetów.

any() i all(): and i or dla całej listy

Żeby połączyć całą sekwencję warunków, użyj wbudowanych funkcji all() (and dla wszystkich elementów) i any() (or dla wszystkich elementów). Obie skracają obliczenia w ten sam sposób:

W przeciwieństwie do and i or, any() i all() zawsze zwracają wartość logiczną.

Częste błędy

Porównywanie jednej zmiennej z kilkoma wartościami przez or. Ten warunek jest zawsze prawdziwy:

Python czyta pierwszy warunek jako (color == "red") or "blue". Porównanie daje False, więc or zwraca "blue", czyli niepusty napis, który jest truthy. Powtórz porównanie po obu stronach albo, jeszcze lepiej, sprawdź przynależność przez in.

Pisanie && albo ||. Oba dają SyntaxError. Używaj and i or.

Oczekiwanie wartości logicznej od and/or. x = a or b zapisuje samo a albo b. Często właśnie o to chodzi, ale jeśli funkcja ma zwrócić True albo False, zamień wynik przez bool().

Poleganie na priorytetach w mieszanych warunkach. a or b and c jest poprawne i dobrze zdefiniowane, ale dodaj nawiasy, żeby nikt nie musiał pamiętać reguły.

Najczęściej zadawane pytania

Co robi operator and w Pythonie?

a and b jest prawdziwe tylko wtedy, gdy obie strony są prawdziwe. Python najpierw oblicza a; jeśli a jest falsy, zwraca a bez patrzenia na b, a w przeciwnym razie zwraca b. Dla zwykłych wartości logicznych daje to znany wynik: True and False to False.

Dlaczego 0 or 5 zwraca 5, a nie True?

or i and zwracają jeden ze swoich operandów, a nie nową wartość logiczną. x or y zwraca x, jeśli x jest truthy, a w przeciwnym razie y. 0 jest falsy, więc 0 or 5 zwraca 5. Opakuj wyrażenie w bool(), jeśli potrzebujesz prawdziwego True albo False.

Czym różni się and od & w Pythonie?

and to operator logiczny: sprawdza truthiness i obliczanie może się na nim skrócić. & to operator bitowy: na liczbach całkowitych łączy bity (6 & 3 to 2), na zbiorach daje część wspólną i zawsze oblicza obie strony. W warunkach if używaj and. Wyjątkiem są NumPy i pandas, gdzie & oznacza „i” element po elemencie.

Co wykonuje się pierwsze w Pythonie: and czy or?

Najsilniej wiąże not, potem and, a na końcu or. Zatem a or b and c znaczy a or (b and c), a not a or b znaczy (not a) or b. Porównania, takie jak == i <, wiążą silniej niż wszystkie trzy.

Czy mogę używać && i || w Pythonie?

Nie. && i || w Pythonie dają SyntaxError. Operatory logiczne to słowa and, or i not. Pojedyncze & albo | jest poprawne, ale znaczy coś innego (bitowe i/lub).

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ