【问题标题】:Finding maximum of a list of lists by sum of elements in Python通过Python中的元素总和查找列表列表的最大值
【发布时间】:2011-02-15 07:43:04
【问题描述】:

在列表列表中,我们想要进行的比较是列表的总和,在 Python 中,maximumBy(高阶函数采用比较函数进行测试)的惯用方式是什么?

这是一个 Haskell 实现和示例输出:

> maximumBy (compare `on` sum) [[1,2,3],[4,5,6],[1,3,5]]
> [4,5,6]

以及这些基本库函数的实现,只是为了完整性(以防你想使用 reduce 或其他东西:)

maximumBy cmp xs =  foldl1 maxBy xs
    where
       maxBy x y = case cmp x y of GT -> x; _ -> y

k `on` f = \x y -> f x `k` f y

sum      =  foldl' (+) 0

【问题讨论】:

    标签: python list haskell higher-order-functions


    【解决方案1】:

    从 Python 2.5 开始,您可以将 max 与关键参数一起使用:

    >>> max(a, key=sum)
    [4, 5, 6]
    

    【讨论】:

    • max(a) 似乎做同样的事情。
    • @titaniumdecoy:默认行为是按字典顺序排列的,碰巧会对此输入数据给出相同的结果,但通常会给出不同的答案。
    • 你现在如何找到这个最大子列表的索引。在上述情况下,它将是 2
    【解决方案2】:

    效率不是很高,但是:

    reduce(lambda x,y: x if sum(x)>sum(y) else y, [[1,2,3],[4,5,6],[1,3,5]])
    

    【讨论】:

    • 将此与@Mark 的正确答案进行比较是一种令人愉快的方式,可以说明为什么 Python 程序员最好忘记 reduce(幸好它不是内置的-在 Py3 中还有更多!-)。
    • @Alex:如果有人使用 for 循环发布了一个答案,这也比 Mark 的答案更笨拙,你会认为 python 程序员最好忘记 for 循环吗?
    • @sepp2k:for 循环是一种令人愉快的方式来展示为什么 Python 程序员应该使用列表推导式。说真的,for 循环并不总是有替代品,但reduce 通常并非如此。尽管我个人很喜欢map/filter/reduce 三位一体,但亚历克斯是对的,因为通常有更好的方法。
    • @outis,我会说“在 Python 中通常有更好的方法 ”——我不会在没有限定条件的情况下这么说,因为在,例如,Haskell 或 Lisp。但是,我们确实同意要点;-)。
    • 在这种情况下您只能消除reduce,因为max 本身本质上是reduce 硬编码以使用二进制max 函数。这并不能证明reduce 在一般情况下没有用。它只是表明,对于您的特定情况,如果有一个专门的功能,您应该使用它。
    【解决方案3】:

    如果 max 没有 key 参数,您可以显式编码 DSU 模式:

    max(izip(imap(sum,a),a))[1]
    

    izipimap 来自 python 2 中的 itertools 模块,它们执行 zip 和 map 的操作,但懒惰地使用 Python 生成器,以避免使用中间列表。在 Python 3 中,内置的 map 和 zip 是惰性的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-12
      • 2018-03-18
      • 1970-01-01
      • 2020-12-05
      • 2023-01-02
      • 2015-01-17
      • 2021-01-01
      • 1970-01-01
      相关资源
      最近更新 更多