5.9 Porównania

W przeciwieństwie do języka C, w Pythonie wszystkie operacje porównań mają taki sam priorytet, który jest niższy od priorytetu wszystkich operacji arytmetycznych, przesunięć i bitowych. Również w przeciwieństwie do C wyrażenia postaci a < b < c mają tradycyjne matematyczne znaczenie:  

comparison  ::=  or_expr ( comp_operator or_expr )*
comp_operator  ::=  "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="
    | "is" ["not"] | ["not"] "in"
Pobierz całą gramatykę w postaci tekstowej.

Wynikami porównań są wartości logiczne: True oznaczająca prawdę lub False oznaczająca fałsz.

Porównania mogą być dowolnie łączone, np. x < y <= z jest równoważne zapisowi x < y and y <= z, z wyjątkiem tego, że y jest wartościowane tylko raz (jednak w obu przypadkach z nie jest wartościowane w ogóle, jeśli warunek x < y okaże się być fałszywy).  

Formalnie, jeśli a, b, c, ..., y, z są wyrażeniami, a opa, opb, ..., opy są operacjami porównań, wówczas a opa b opb c ...y opy z jest równoważne zapisowi a opa b and b opb c and ... y opy z, z wyjątkiem tego, że każde z wyrażeń jest wartościowane co najwyżej raz.

Zwróćmy uwagę, że z wyrażenia postaci a opa b opb c nie wynika żadnego typu porównanie pomiędzy a i c, w związku z czym np. x < y > z jest zapisem w pełni poprawnym (choć pewnie niezbyt eleganckim).

Zapisy <> oraz != są równoważne. Dla spójności z językiem C preferowany jest zapis !=. W każdym z miejsc poniżej, w których mowa o !=, dopuszczalne jest użycie <>. Formę <> uważa się za przestarzałą.

Operatory <, >, ==, >=, <= oraz != porównują wartości dwóch obiektów. Obiekty nie muszą być tego samego typu. Jeśli oba są liczbami, następuje ich konwersja do wspólnego typu. W przeciwnym wypadku, obiekty różnych typów są zawsze uznawane za nierówne, zaś ich porządek ustalany jest arbitralnie, choć w sposób spójny.

(Ta dość niezwykła definicja porównań została użyta, aby uprościć definicje pewnych operacji, np. sortowania oraz operatorów in czy not in. W przyszłości reguły porównywania obiektów różnych typów mogą ulec zmianie.)

Porównanie obiektów tego samego typu zależy od typu:

Operatory in oraz not in dokonują sprawdzenia przynależności. Wyrażenie x in s jest prawdziwe, jeśli x jest elementem zbioru s, a fałszywe w przeciwnym wypadku. Wyrażenie x not in s daje w wyniku negację logiczną wartości wyrażenia x in s. Tradycyjnie sprawdzanie przynależności było związane z sekwencjami -- obiekt jest elementem zbioru, jeśli zbiór jest sekwencją i jeden z elementów sekwencji jest równy temu obiektowi. Sprawdzanie przynależności mogą jednak obsługiwać również obiekty nie będące sekwencjami. W szczególności, typ słownikowy wykorzystuje tę operację jako bardziej elegancką formę sprawdzenia obecności wartości wśród kluczy słownika (klucz in słownik). Inne typy odwzorowawcze mogą funkcjonować w podobny sposób.

W przypadku list i krotek, wyrażenie x in y jest prawdziwe wtedy i tylko wtedy, gdy x jest fragmentem y, co odpowiada prawdziwości wyrażenia y.find(x) != -1. Należy przy tym podkreślić, że x i y nie muszą być tego samego typu, więc u'ab' in 'abc' da wartość True. Przyjmuje się, że napisy puste są zawsze częścią dowolnego innego napisu, więc wyrażenie "" in "abc" da w wyniku wartość True. Zmieniono w wersji 2.3: W poprzednich wersjach Pythona x musiał być napisem o długości 1.

W przypadku typów napisowych oraz Unicode, wyrażenie x in y jest prawdziwe wtedy i tylko wtedy, gdy istnieje taki indeks i, dla którego prawdziwe jest wyrażenie x == y[i]. Jeśli x nie jest napisem lub obiektem Unicode o długości 1, generowany jest wyjątek TypeError.

W przypadku klas zdefiniowanych przez użytkownika, które zawierają metodę __contains__(), wyrażenie x in y jest prawdziwe wtedy i tylko wtedy, gdy prawdziwe jest wyrażenie y.__contains__(x).

W przypadku klas zdefiniowanych przez użytkownika, które nie zawierają metody __contains__(), lecz definiują metodę __getitem__(), wyrażenie x in y jest prawdziwe wtedy i tylko wtedy, gdy istnieje nieujemna liczba całkowita i będąca indeksem, dla której x == y[i] jest prawdziwe, natomiast przy wszystkich niższych indeksach nie jest generowany wyjątek IndexError. (Jeśli przy wywołaniu metody zostanie wygenerowany inny wyjątek, wynik będzie taki, jakby został on wygenerowany przez użycie operatora in).

Operator not in definiuje się jako zwracający wartość logiczną będącą negacją tej, którą zwraca in.  

Operatory is oraz is not sprawdzają tożsamość obiektu: x is y jest prawdziwe wtedy i tylko wtedy, gdy x i y są tymi samymi obiektami. Wartością x is not y jest negacja logiczna odmiany z operatorem is.  



... równe.5.3
Na poziomie implementacji jest to obliczane w sposób efektywny, bez rzeczywistego tworzenia list i ich sortowania.
... sposób.5.4
We wcześniejszych wersjach Pythona wykonywane było leksykograficzne porównanie posortowanych list par (klucz, wartość), jednak operacja ta była zbyt czasochłonna dla dość częstego przypadku sprawdzania równości. W jeszcze wcześniejszych wersjach słowniki były porównywane wyłącznie w oparciu o ich tożsamości, co prowadziło często do nieoczekiwanych wyników, gdyż wiele osób sprawdzało np. czy słownik jest pusty, poprzez porównanie go z {}.
Zajrzyj do Informacji na temat tej publikacji... aby pomóc w jej rozwoju.