2015-02-01 13 views
5

Kalka powrotem ValueError: cannot convert float NaN to integer I okazało się, że linia:Dlaczego python max ("a", 5) zwraca wartość ciągu?

max('a', 5) 
max(5, 'a') 

powróci a zamiast 5.

W powyższym przypadku użyłem przykładowy ciąg a ale w moim konkretnym przypadku łańcuch jest NaN (wynik procesu dopasowywania, który się nie zbiegał).

Jakie są przesłanki tego zachowania? Dlaczego Python nie rozpoznaje automatycznie, że jest tam ciąg znaków i że powinien zwrócić numer?

Jeszcze bardziej ciekawy jest fakt, że min()robi pracy zgodnie z oczekiwaniami od:

min('a', 5) 
min(5, 'a') 

zwrotów 5.

+2

Powiązane: [Dlaczego żaden nie jest najmniejszy w pythonie?] (Http: // stackoverflow.com/q/22040724) –

+1

możliwy duplikat [Jak Python porównuje ciąg i int?] (http://stackoverflow.com/questions/3270680/how-does-python-compare-string-and-int) – lightandlight

Odpowiedz

11

w Pythonie 2, wartości liczbowe zawsze porządek przed struny i prawie wszystkie inne typy:

>>> sorted(['a', 5]) 
[5, 'a'] 

Liczby są więc uważane mniejszy niż strun. Podczas korzystania z max() oznacza to, że ciąg jest wybierany przez liczbę.

Te liczby są mniejsze, to arbitralny wybór przy wdrażaniu. Zobacz Comparisons documentation:

Operatorzy <, >, ==, >=, <= i != porównanie wartości dwóch obiektów. Obiekty nie muszą mieć tego samego typu. Jeśli oba są liczbami, są one konwertowane do wspólnego typu. W przeciwnym razie obiekty różnych typów zawsze będą porównywać nierówności i będą uporządkowane konsekwentnie, ale arbitralnie.

Pogrubiony nacisk mój.

Python 2 bardzo się starał, aby typy heterogeniczne można było sortować, co spowodowało wiele trudnych do rozwiązania problemów, takich jak programiści próbujący porównać liczby całkowite z ciągami i uzyskując nieoczekiwane wyniki. Python 3 naprawił ten błąd; Dostaniesz TypeError zamiast:

>>> max(5, 'a') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unorderable types: str() > int() 

mam written elsewhere about the ordering rules, a nawet re-implemented the Python 2 rules for Python 3, jeśli naprawdę chciał te plecy.

+0

I ' nie jest downvoter, ale nie jest ** prawdą, że "wartości liczbowe zawsze sortują przed innymi typami" - spróbuj np. 'posortowane (None, 23))' i często zobaczysz 'None' chociaż nie jest to typ numeryczny. To ** jest **, lub raczej ** było ** gdy Py2 jest historią, naprawdę arbitralna dekretacja –

+0

@AlexMartelli: Brak jest jedynym wyjątkiem; Nie chciałem jednak rozłożyć całego zestawu zasad. Łączę się z odpowiedzią, w której zajrzałem do głębi. Wybory były niegdyś arbitralne, ale ponieważ od tego czasu się nie zmieniły, teraz są raczej osadzone w kamieniu. :-) –

+1

@AlexMartelli: poprawiono złe sformułowanie w pierwszym zdaniu. –

2

W ciągi tekstowe CPython 2.x są zawsze większe niż liczby, dlatego widzisz te zachowania.

OTOH, nie rozumiem, dlaczego uważasz, że 5 jest "oczywiście" większy niż "a" ... Wartości różnych typów są porównywalne tylko dla wygody (np. Jeśli budujesz drzewo RB z niejednorodnymi klawiszami, aby wszystko było porównywalne), a takie porównania definiują ścisłą słabą kolejność, ale porównania między typami nie są w żaden sposób sensowne (jak można porównać liczbę do ciągu lub obiektu?), tylko spójne.

Powiązane problemy