Jak działa porównanie krotek w Pythonie?

178

Czytałem książkę o programowaniu w języku Core Python , a autor pokazuje przykład:

(4, 5) < (3, 5) # Equals false

Więc zastanawiam się, jak / dlaczego jest równe fałszowi? Jak Python porównuje te dwie krotki?

Przy okazji, nie jest to wyjaśnione w książce.

Paulo
źródło

Odpowiedzi:

190

Krotki są porównywane pozycja po pozycji: pierwszy element pierwszej krotki jest porównywany z pierwszym elementem drugiej krotki; jeśli nie są równe (tj. pierwsza jest większa lub mniejsza od drugiej), to jest to wynik porównania, w przeciwnym razie brana jest pod uwagę druga pozycja, potem trzecia i tak dalej.

Zobacz wspólne operacje sekwencyjne :

Sekwencje tego samego typu również obsługują porównania. W szczególności krotki i listy są porównywane leksykograficznie poprzez porównywanie odpowiednich elementów. Oznacza to, że aby porównać równe, każdy element musi porównać równe, a dwie sekwencje muszą być tego samego typu i mieć tę samą długość.

Dodatkowe informacje można znaleźć również w porównaniach wartości :

Porównanie leksykograficzne między wbudowanymi zbiorami działa w następujący sposób:

  • Aby dwie kolekcje były porównywane równo, muszą być tego samego typu, mieć tę samą długość, a każda para odpowiadających sobie elementów musi być równa (na przykład [1,2] == (1,2) jest fałszywa, ponieważ typ nie jest taki sam).
  • Kolekcje obsługujące porównywanie zamówień są uporządkowane tak samo, jak ich pierwsze nierówne elementy (na przykład [1,2,x] <= [1,2,y]mają tę samą wartość co x <= y). Jeśli odpowiedni element nie istnieje, w pierwszej kolejności jest sortowana krótsza kolekcja (na przykład [1,2] < [1,2,3]true).

Jeśli nie są równe, sekwencje są uporządkowane tak samo, jak ich pierwsze różniące się elementy. Na przykład cmp ([1,2, x], [1,2, y]) zwraca to samo co cmp (x, y). Jeśli odpowiedni element nie istnieje, krótsza sekwencja jest uważana za mniejszą (na przykład [1,2] <[1,2,3] zwraca True).

Uwaga 1 : <i >nie oznaczają „mniejszy niż” i „większy niż”, ale „jest przed” i „jest po”: więc (0, 1) „jest przed” (1, 0).

Uwaga 2 : krotki nie mogą być traktowane jako wektory w przestrzeni n-wymiarowej , porównane na podstawie ich długości.

Uwaga 3 : odnosząc się do pytania /programming/36911617/python-2-tuple-comparison : nie myśl, że krotka jest „większa” od innej tylko wtedy, gdy którykolwiek element pierwszego jest większy niż odpowiadający jeden w drugim.

Don
źródło
4
Może to być mylące, gdy mówisz o <i >. Na przykład (0, 1) < (1, 0)szacuje do True.
Brak
4
@CMCDragonkai - tak. spróbuj: x = tuple([0 for _ in range(n)])i zrób to samo dla y. Ustawienie n = 100, 1000, 10 000 i 100 000 i uruchomienie %timeit x==ydało wartości taktowania odpowiednio 0,5, 4,6, 43,9 i 443 mikrosekund, czyli mniej więcej tak blisko O (n), jak to praktycznie możliwe.
Michael Scott Cuthbert
8
@ J.Money, jak myślisz, dlaczego może to być mylące?
Don
1
@CharlieParker <i >nie oznacza „mniejszy niż” i „większy niż”, ale „przychodzi przed” i „przychodzi po”: więc (0, 1)„przychodzi przed”(1, 0)
Don
3
@Don Myślę, że nie jest dla nas jasne, jaki rodzaj rozkazu narzucić krotce. Myślę, że python po prostu traktuje to jako liczby, sprawdzając najpierw największą znaczącą cyfrę, a przejście do łamania umiera ... (w sposób elementarny)
Charlie Parker
20

Dokumentacja Pythona wyjaśnia to.

Krotki i listy są porównywane leksykograficznie przy użyciu porównania odpowiednich elementów. Oznacza to, że aby porównać równe, każdy element musi porównać równe, a dwie sekwencje muszą być tego samego typu i mieć tę samą długość.

Keith
źródło
Strona, do której prowadzi ta odpowiedź, nie wydaje się zawierać cytowanego tekstu.
plugwash
0

Dokumentacja Pythona 2.5 dobrze to wyjaśnia.

Krotki i listy są porównywane leksykograficznie przy użyciu porównania odpowiednich elementów. Oznacza to, że aby porównać równe, każdy element musi porównać równe, a dwie sekwencje muszą być tego samego typu i mieć tę samą długość.

Jeśli nie są równe, sekwencje są uporządkowane tak samo, jak ich pierwsze różniące się elementy. Na przykład cmp ([1,2, x], [1,2, y]) zwraca to samo co cmp (x, y). Jeśli odpowiadający element nie istnieje, najpierw uporządkowana jest krótsza sekwencja (na przykład [1,2] <[1,2,3]).

Niestety, wydaje się, że ta strona zniknęła z dokumentacji nowszych wersji.

plugwash
źródło
0
Miałem wcześniej pewne zamieszanie w związku z porównaniem liczb całkowitych, więc wyjaśnię to jako bardziej przyjazne dla początkujących na przykładzie

a = ('A','B','C') # see it as the string "ABC" b = ('A','B','D')

A jest konwertowane na odpowiadający mu kod ASCII ord('A') #65 samo dla innych elementów

Tak więc, >> a>b # True można myśleć o nim jako porównanie między ciąg (to jest dokładnie, w rzeczywistości)

to samo dotyczy liczb całkowitych.

x = (1,2,2) # see it the string "123" y = (1,2,3) x > y # False

ponieważ (1 nie jest większe niż 1, przejdź do następnego, 2 nie jest większe niż 2, przejdź do następnych 2 jest mniejsze niż trzy -leksykograficznie -)

Kluczowy punkt jest wspomniany w powyższej odpowiedzi

myśl o tym, że element jest, zanim inny alfabetycznie nie element nie jest większy niż element iw tym przypadku traktuj wszystkie elementy krotki jako jeden ciąg.

Bishoy Abd
źródło
2
(1,2,3) > (1,2,2)dajeTrue
Vishal Singh