Сортировка кортежей python содержит несопоставимые элементы

#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 в приведенном выше коде пытается найти первые неравные элементы и, если не найден, делегирует сравнение размеру кортежей.