#python #sorting #tuples
#python #сортировка #Кортежи
Вопрос:
При попытке сравнить словари python выдает ошибку типа:
{"a" : "b"} < {"a" : "b"} # TypeError
При попытке сравнить кортежи python делает это поэлементно:
(1, 2) > (1, 1) # True
Поэтому я ожидал, что сравнение кортежей, содержащих словари, приведет к ошибке типа, если элементы, предшествующие словарям, будут равны, потому что тогда он будет вынужден сравнивать словари, что вызовет ошибку типа. Это не так:
(3, {"a" : "b"}) < (3, {"a" : "b"}) # False, no TypeError
Я прочитал документацию, которую смог найти относительно сортировки Python, и не увидел ничего, документирующего это поведение. Могу ли я рассчитывать на то, что это поведение останется неизменным в будущих версиях?
Комментарии:
1. @DaniMesejo но
(3, {"a" : "b"}) < (3, {"c" : "d"})
выдает ошибку.2. @Bobby
(3, {"a" : "b"}) < (3, {"a" : "b"}) # False, no TypeError
выдает ошибку.>>> (3, {"a" : "b"}) < (3, {"c" : "d"}) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: '<' not supported between instances of 'dict' and 'dict'
Ответ №1:
Это объясняется в документах:
Лексикографическое сравнение встроенных коллекций работает следующим образом:
Чтобы две коллекции сравнивались одинаково, они должны быть одного типа, иметь одинаковую длину, и каждая пара соответствующих элементов должна сравниваться одинаково (например, [1,2] == (1,2) равно false, потому что тип не совпадает).
Коллекции, поддерживающие сравнение порядков, упорядочиваются так же, как и их первые неравные элементы (например, [1,2,x] <= [1,2,y] имеет то же значение, что и x <= y). Если соответствующий элемент не существует, сначала упорядочивается более короткая коллекция (например, [1,2] < [1,2,3] имеет значение true).
Итак, первое, что будет сделано при сравнении кортежей, — это найти неравные элементы, так как в вашем кортеже нет неравных элементов False
, и для этого нет необходимости вызывать код <
.
Это дополнительно подтверждается, если посмотреть на реализацию сравнения кортежей:
for (i = 0; i < vlen amp;amp; i < wlen; i ) {
int k = PyObject_RichCompareBool(vt->ob_item[i],
wt->ob_item[i], Py_EQ);
if (k < 0)
return NULL;
if (!k)
break;
}
if (i >= vlen || i >= wlen) {
/* No more items to compare -- compare sizes */
Py_RETURN_RICHCOMPARE(vlen, wlen, op);
}
Цикл for в приведенном выше коде пытается найти первые неравные элементы и, если не найден, делегирует сравнение размеру кортежей.