Путаница в отношении минимальной викторины Python

Только что я увидел викторину на на этой странице:

>>> x, y = ???
>>> min(x, y) == min(y, x)
False

Пример ответа

x, y = {0}, {1}

Из документации я знаю, что:

min (iterable [, key = func]) → значение
min (a, b, c,... [, key = func]) → значение

С одним итерабельным аргументом верните его наименьший элемент.
С двумя или более аргументами верните наименьший аргумент.

Но почему min({0},{1})={0} и min({1},{0})={1}?

Я также пробовал несколько других:

min({0,2},1)   # 1
min(1,{0,2})   # 1
min({1},[2,3]) # [2,3]
min([2,3],1)   # 1

Ответы

Ответ 1

min выполняется примерно так:

def min(*args):
    least = args[0]
    for arg in args:
        if arg < least:
            least = arg
    return least

То, как работают операторы сравнения для множеств, нарушает одно из предположений, которое это неявно делает: для каждой пары объектов либо они равны, либо a < b или b < a. Ни {0}, ни {1} не сравниваются друг с другом, поэтому min дает вам непоследовательные ответы.

Другие результаты, которые вы видите, связаны с правилами, определяющими порядок использования Python для смешанных типов. A set и a int не сопоставимы - ни один из этих типов не определяет правило для сравнения с другим. Это приводит к тому, что Python 2 применяет правило "произвольный, но последовательный порядок" - один из типов выбирается как "нижний" тип, и он останется нижним типом для времени жизни программы. На практике это будет одинаково для всего кода, который вы запускаете, потому что он реализуется путем сравнения имен типов в алфавитном порядке - но теоретически это может измениться.

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

>>> 1 < {0}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < set()

Ответ 2

Операторы сравнения <, <=, >= и > проверяют, является ли один набор строгим подмножеством, подмножеством, надмножеством или строгим надмножеством другого.

{0} и {1} для всех из них False, поэтому результат зависит от порядка проверки и оператора.

Ответ 3

Ключевым моментом здесь является то, что два набора не являются подмножествами друг друга, поэтому оба являются False для <, хотя они не равны:

>>> {0} < {1}
False
>>> {0} > {1}
False
>>> {0} == {1}
False

Итак, какой из них меньше? Тот факт, что набор не обеспечивает строгое слабое упорядочение, означает, что нет правильного ответа.