Странные сравнения в Python

Я дурачился и наткнулся на то, чего не понимаю...

Вопрос 1:

a = [1,2,3]
b = [1,2,3,4]

len(a) < b

Результат — True, но действительно ли это сравнение длины двух списков? Вроде бы, так как это тоже Верно...

a = [15,32,7]
len(a) < b

Вопрос 2:

Что происходит, когда мы пытаемся сравнить целые числа со списками? Почему все это правда (я предполагаю, что есть общее объяснение...)...

3 < b
20 < b
float('inf') < b
None < b
(lambda x: (x**x)**x) < b

...и эти ложные?

'poo' < b
'0' < b

person myedibleenso    schedule 12.10.2013    source источник


Ответы (3)


В Python 2.x элементы разнородных типов, которые нельзя сравнивать напрямую, сравниваются по именам их типов. Таким образом, все целые числа меньше всех списков, потому что "int" меньше "list". По той же причине все str больше, чем все int и float.

Это неинтуитивное поведение (которое, я полагаю, было введено для того, чтобы элементы одного типа сортировались вместе в гетерогенном списке) было удалено в Python 3, что создает исключение для этих сравнений.

person kindall    schedule 12.10.2013
comment
Подал заявку на (2, ,3, 4) < [2, 3, 4] также ? Я имею в виду, что это = "tuple" < "list" = False. - person Grijesh Chauhan; 12.10.2013
comment
Спасибо, это очень полезно. А как насчет len(list1) ‹ list2? Действительно ли он сравнивает длины списков, как кажется? - person myedibleenso; 12.10.2013
comment
len(list1) — целое число, а list2 — список. Как я уже сказал, целое число всегда меньше списка. Длины списков не сравниваются. - person kindall; 12.10.2013
comment
@GrjeshChauhan: Возможно, вы уловили мой ответ до того, как я добавил прямое сравнение с ним. Кортежи и списки можно сравнивать друг с другом, потому что они оба являются последовательностями. - person kindall; 12.10.2013
comment
@kindall Да, но я только что попробовал на своем Python3.3 (2, ,3, 4) < [2, 3, 4], и получил TypeError: Unoderable Types tuple() < list(). - person Grijesh Chauhan; 12.10.2013
comment
kindall: len([15, 32, 7, 45, 61]) ‹ [1, 2, 3, 4] — ложь - person myedibleenso; 12.10.2013
comment
@GrjeshChauhan: kindall прямо сказал, что это поведение было удалено в Python 3 и что оно вызывает исключение. - person DSM; 12.10.2013
comment
@DSM Хорошо, прочитайте еще раз, второй пункт понял, спасибо! - person Grijesh Chauhan; 12.10.2013

Из документов по типам данных:

Объекты последовательности можно сравнивать с другими объектами с тем же типом последовательности. При сравнении используется лексикографический порядок: сначала сравниваются первые два элемента, и если они различаются, это определяет результат сравнения; если они равны, сравниваются следующие два элемента и так далее, пока не будет исчерпана любая последовательность.

И

Обратите внимание, что сравнение объектов разных типов допустимо. Результат детерминирован, но произволен: типы упорядочены по их именам. Таким образом, список всегда меньше строки, строка всегда меньше кортежа и т. д. 1 Смешанные числовые типы сравниваются в соответствии с их числовым значением, поэтому 0 равно 0,0 и т. д.

И, в частности,

Сноски 1 Не следует полагаться на правила сравнения объектов разных типов; они могут измениться в будущей версии языка.

person roippi    schedule 12.10.2013
comment
Спасибо, немного об объектах последовательности было очень полезно. - person myedibleenso; 12.10.2013

Другие ответы хорошо объясняют, что происходит, но правильный способ сравнить длины

len(a) < len(b)
person James Robinson    schedule 12.10.2013
comment
Я не думаю, что у ОП были проблемы со сравнением длин. Он хотел объяснить, почему он видел поведение, свидетелем которого он был. Этот ответ, хотя и правильный, на самом деле не ориентирован на потребности ОП. - person ; 12.10.2013
comment
Я тоже так думал, за исключением этой строки, но действительно ли она сравнивает длину двух списков. Вот я и подумал выкинуть его на всякий случай. - person James Robinson; 12.10.2013