如果是平局,Python会选择哪个最大值?


72

max()在Python中使用该函数在列表(或元组,字典等)中查找最大值时,并且最大值与并列,Python会选择哪一个?它是随机的吗?

例如,如果有一个元组列表,并且key=根据元组的第一个元素选择一个最大值(使用),但是有不同的第二个元素,则这是有意义的。Python如何决定选择哪个最大?


7
请不要尝试依赖任何一种排序功能。
hugomg


2
我同意missingno,这不是您应该依靠的行为。我希望您只是出于调试目的。如果您关心元组的第二个元素(在您的假设示例中),则应始终在key =函数中考虑它。
codewarrior

@codewarrior有时任何最大值都可以,但是您仍然想要保证对于相同的输入,相同的对象将是最大值。
pfctdayelise

Answers:


78

它选择看到的第一个元素。请参阅有关文档max()

如果有多个最大项,则该函数返回遇到的第一个项。这与其他排序稳定性保存工具(例如sorted(iterable, key=keyfunc, reverse=True)[0]和)一致heapq.nlargest(1, iterable, key=keyfunc)

在源代码中实现此方法./Python/bltinmodule.c通过builtin_max,它包装在更一般的min_max功能

min_max将遍历这些值并用于PyObject_RichCompareBool查看它们是否大于当前值。如果是这样,则较大的值将替换它。相等的值将被跳过。

结果是在平局的情况下将选择第一个最大值。


@DoubleAA字典的排序方式是,从CPython 3.6起开始插入哪个项,然后从CPython 3.6起开始插入,以及从Python 3.7开始的其他任何Python实现
Boris

22

从经验测试来看,如果出现平局,则max()and会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')

Jeremy的优秀侦探证实,这确实是这样的。


15

对于Python 3,在max()有联系的情况下,行为不再仅仅是实现细节,如其他答案中所述。现在可以保证该功能,因为Python 3文档明确声明:

如果有多个最大项,则该函数返回遇到的第一个项。这与其他排序稳定性保存工具(例如sorted(iterable, key=keyfunc, reverse=True)[0]和)一致 heapq.nlargest(1, iterable, key=keyfunc)


克里斯·我想我的问题元获得了你一些当之无愧upvotes :) meta.stackoverflow.com/questions/352439/...
让·弗朗索瓦·法布尔

1
有没有办法获得遇到的最后一个而不是第一个(不必求助于排序)?
lifebalance 2009年

2
@lifebalance在应用max()之前反转列表
Chris_Rands

@lifebalance或者执行此操作。(略有不同,即得到索引)
user202729

4

您的问题有些引人注目。在对数据结构进行排序时,通常希望保持出于比较目的被认为相等的对象的相对顺序。这将称为稳定排序

如果您绝对需要此功能,则可以执行sort()它将保持稳定,然后了解相对于原始列表的顺序。

根据python本身,我不相信您会在调用时获得任何保证max()。其他答案给出了cpython的答案,但是其他实现(IronPython,Jython)的功能可能有所不同。


0

对于IMO的Python 2版本,我相信您不能假定max()在出现领带的情况下返回列表中的第一个最大元素。我之所以这样认为是因为max()应该实现真正的数学函数max,该函数用于具有总顺序的集合,并且元素不具有任何“隐藏信息”。

(我会假设其他人都进行了正确的研究,而Python文档并未对此提供任何保证max()。)

(通常,关于库函数的行为,您可能会问无数个问题,几乎都无法回答。例如:将max()使用多少堆栈空间?它将使用SSE吗?多少?临时内存吗?是否可以多次比较同一对对象(如果比较有副作用)?对于“特殊”已知数据结构,它可以比O(n)时间运行得更快吗?等)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.