Какой максимум Python выбирает в случае галстука?

При использовании функции max() в Python, чтобы найти максимальное значение в списке (или кортеж, dict и т.д.), и есть связь для максимального значения, которую выбирает Python? Это случайное?

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

Я работаю в Python v2.6.

+62
21 июл. '11 в 21:25
источник поделиться
5 ответов

На Python 2 это не указано в документации и не находится в переносимом в Python разделе стандартной библиотеки, поэтому это поведение может различаться в разных реализациях.

В источнике для CPython 2.7 это реализовано в ./Python/bltinmodule.c by builtin_max [ source ] которое обертывает более общую функцию min_max [ source ].

min_max будет перебирать значения и использовать PyObject_RichCompareBool [ docs ], чтобы узнать, больше ли они текущего значения. Если это так, то большее значение заменяет его. Равные значения будут пропущены.

В результате первый максимум будет выбран в случае галстука.

+66
21 июл. '11 в 21:34
источник

Из эмпирического тестирования кажется, что max() и min() в списке вернут первое в списке, которое соответствует max()/min() в случае равенства:

>>> test = [(1, "a"), (1, "b"), (2, "c"), (2, "d")]
>>> max(test, key=lambda x: x[0])
(2, 'c')
>>> test = [(1, "a"), (1, "b"), (2, "d"), (2, "c")]
>>> max(test, key=lambda x: x[0])
(2, 'd')
>>> min(test, key=lambda x: x[0])
(1, 'a')
>>> test = [(1, "b"), (1, "a"), (2, "d"), (2, "c")]
>>> min(test, key=lambda x: x[0])
(1, 'b')

И Джереми отлично следит, что это действительно так.

+20
21 июл. '11 в 21:30
источник

Связанные вопросы


Похожие вопросы

Для Python 3 поведение max() в случае связей больше не просто деталь реализации, подробно описанный в других ответах. Теперь функция гарантирована, так как Python 3 docs явно заявляет:

Если несколько элементов являются максимальными, функция возвращает первый встречается. Это согласуется с другим сохранением стабильности сортировки такие инструменты, как сортировка (iterable, key = keyfunc, reverse = True) [0] и heapq.nlargest(1, iterable, key = keyfunc).

+14
24 мая '17 в 8:53
источник

Ваш вопрос несколько приводит к заметке. При сортировке структуры данных часто возникает желание сохранить относительный порядок объектов, которые считаются равными для целей сравнения. Это будет известно как стабильная сортировка.

Если вам абсолютно нужна эта функция, вы можете сделать sort(), который будет стабильным, а затем получить информацию о порядке относительно исходный список.

В соответствии с самим python я не верю, что вы получаете гарантию того, какой элемент вы получите, когда вы вызываете max(). Другие ответы дают ответ cpython, но другие реализации (IronPython, Jython) могут работать по-разному.

+6
21 июл. '11 в 21:37
источник

Для версий Python 2, IMO, я полагаю, вы не можете предположить, что max() возвращает первый максимальный элемент в списке в случае связей. У меня есть это убеждение, потому что max() предполагается реализовать истинную математическую функцию max, которая используется в наборах, имеющих полный порядок, и где элементы не имеют никакой "скрытой информации".

(Я предполагаю, что другие исследовали правильно, и документация Python не дает никаких гарантий для max().)

(В общем, существует бесконечное количество вопросов, которые вы можете задать о поведении библиотечной функции, и почти все из них не могут быть отвечены. Например: Сколько будет пространства стека max()? он использует SSE? Сколько временная память? Может ли она сравнивать одну и ту же пару объектов более одного раза (если сравнение имеет побочный эффект)? Может ли она работать быстрее, чем O (n) время для "специальных" известных структур данных?.)

+2
21 июл. '11 в 21:42
источник

Посмотрите другие вопросы по меткам или Задайте вопрос