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:
a | b | a and b | a or b | not a |
|---|---|---|---|---|
True | True | True | True | False |
True | False | False | True | False |
False | True | False | True | True |
False | False | False | False | True |
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:
FalseiNone- 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 yzwracax, jeślixjest truthy, a w przeciwnym razie zwracay.x and yzwracax, jeślixjest falsy, a w przeciwnym razie zwracay.
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:
andzatrzymuje się na pierwszej wartości falsy, bo nic dalej nie sprawi, że całe wyrażenie będzie prawdziwe.orzatrzymuje 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/orsprawdzają 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ę. NaTrueiFalsezwracają 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?
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 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).