【问题标题】:Which maximum does Python pick in the case of a tie?在平局的情况下,Python 选择哪个最大值?
【发布时间】:2011-10-10 14:41:48
【问题描述】:

当在 Python 中使用 max() 函数来查找列表(或元组、字典等)中的最大值并且最大值存在平局时,Python 选择哪一个?是随机的吗?

这是相关的,例如,一个人有一个元组列表,一个人根据元组的第一个元素选择最大值(使用key=),但有不同的第二个元素。 Python 如何决定选择哪一个作为最大值?

【问题讨论】:

  • 请不要尝试依赖其中的任何一个来进行排序。
  • 我同意missingno这不是你应该依赖的行为。我希望您只是出于调试目的而询问。如果您关心元组的第二个元素(在您的假设示例中),那么您应该始终在您的 key= 函数中考虑它。
  • @codewarrior 有时任何最大值都可以,但您仍然需要保证对于相同的输入,相同的对象将是最大值。

标签: python max


【解决方案1】:

它选择它看到的第一个元素。见the documentation for max()

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

在源代码中这是实现in ./Python/bltinmodule.c by builtin_max,它包装了more general min_max function

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

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

【讨论】:

  • @DoubleAA 字典按从 CPython 3.6 及更高版本开始首先插入的项目排序,以及从 Python 3.7 开始的任何其他 Python 实现
  • 真的是第一个元素吗?由于 max(['ab','ba']) 返回 'ba',在文档中找不到原因!
【解决方案2】:

对于 Python 3,max() 在 tie 的情况下的行为不再只是其他答案中详述的实现细节。正如Python 3 docs 明确声明的那样,该功能现在得到保证:

如果多个项目是最大的,该函数返回第一个 遭遇。这与其他排序稳定性保持一致 sorted(iterable, key=keyfunc, reverse=True)[0]heapq.nlargest(1, iterable, key=keyfunc).

【讨论】:

  • 克里斯,我认为我关于 meta 的问题为你赢得了当之无愧的支持 :) meta.stackoverflow.com/questions/352439/…
  • 有没有办法在遇到的最后一个,而不是第一个(不必求助于排序)?
  • @lifebalance 在应用 max() 之前反转列表
  • @lifebalance 或者do this。 (略有不同,那一个得到索引)
【解决方案3】:

对于 Python 2 版本,IMO,我相信你不能假设 max() 在 tie 的情况下返回列表中的第一个最大元素。我有这个信念是因为max() 应该实现真正的数学函数max,它用于具有全序且元素没有任何“隐藏信息”的集合。

(我会假设其他人已经正确研究过,Python 文档并没有为max() 提供任何保证。)

(一般来说,关于库函数的行为,你可以问无数个问题,而且几乎所有的问题都无法回答。例如:会有多少堆栈空间max()使用?它会使用 SSE?多少临时内存?它可以多次比较同一对对象(如果比较有副作用)?对于“特殊”已知数据结构,它的运行速度能否超过 O(n) 时间?等等等等)

【讨论】:

    【解决方案4】:

    根据经验测试,如果出现平局,列表中的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')
    

    Jeremy's excellent sleuthing 证实确实如此。

    【讨论】:

    • max(['ab','ba']) 返回什么?猜测??它的'ba'!
    【解决方案5】:

    您的问题在某种程度上引出了一个注释。在对数据结构进行排序时,通常希望保持被认为相等的对象的相对顺序以进行比较。这将被称为stable sort

    如果你绝对需要这个功能,你可以做一个sort()will be stable,然后知道相对于原始列表的顺序。

    就 python 本身而言,我不相信当你调用max() 时你会得到哪个元素的任何保证。其他答案给出了 cpython 答案,但其他实现(IronPython、Jython)的功能可能不同。

    【讨论】:

      猜你喜欢
      • 2016-02-01
      • 2021-08-31
      • 2023-03-18
      • 1970-01-01
      • 2022-10-16
      • 1970-01-01
      相关资源
      最近更新 更多