繁体   English   中英

在 Python 列表中查找最大化/最小化函数的所有元素的最快方法

[英]Fastest way to find all elements that maximize / minimize a function in a Python list

让我们使用一个简单的例子:假设我有一个列表列表

ll = [[1, 2], [1, 3], [2, 3], [1, 2, 3], [2, 3, 4]]

我想找到所有最长的列表,这意味着最大化len函数的所有列表。 我们当然可以

def func(x):
    return len(x)
maxlen = func(max(ll, key=lambda x: func(x)))
res = [l for l in ll if func(l) == maxlen]
print(res)

输出

[[1, 2, 3], [2, 3, 4]]

但是我想知道是否有更有效的方法来做到这一点,尤其是当功能非常昂贵或列表很长时。 有什么建议?

从计算机科学/算法的角度来看,这是一个非常经典的“归约”问题。

所以,伪代码。 老实说,这是非常简单的。

metric():= a mapping from elements to non-negative numbers

winner = []
maxmetric = 0

for element in ll:
  if metric(element) larger than maxmetric:
    winner = [ element ]
    maxmetric = metric(element)
  else if metric(element) equal to maxmetric:
    append element to winner

当功能非常昂贵时

请注意,您为每个元素计算func(x)两次,首先是

maxlen = func(max(ll, key=lambda x: func(x)))

然后在那里

res = [l for l in ll if func(l) == maxlen]

因此存储已经计算的内容将是有益的。 functools.lru_cache允许轻松替换

def func(x):
    return len(x)

使用

import functools
@functools.lru_cache(maxsize=None)
def func(x):
    return len(x)

但是,请注意,由于数据的存储方式,参数必须是可散列的,因此在您的示例中,您首先需要将列表转换为tuple s ie

ll = [(1, 2), (1, 3), (2, 3), (1, 2, 3), (2, 3, 4)]

请参阅文档中的说明以进行进一步讨论

不可以使用如下dictionary(这是O(n)

ll = [[1, 2], [1, 3], [2, 3], [1, 2, 3], [2, 3, 4]]

from collections import defaultdict
dct = defaultdict(list)

for l in ll:
    dct[len(l)].append(l)
    
dct[max(dct)]

输出:

[[1, 2, 3], [2, 3, 4]]


>>> dct
defaultdict(list, {2: [[1, 2], [1, 3], [2, 3]], 3: [[1, 2, 3], [2, 3, 4]]})

或者使用setdefault而没有defaultdict如下所示:

ll = [[1, 2], [1, 3], [2, 3], [1, 2, 3], [2, 3, 4]]

dct = {}
for l in ll:
    dct.setdefault(len(l), []).append(l)

输出:

>>> dct
{2: [[1, 2], [1, 3], [2, 3]], 3: [[1, 2, 3], [2, 3, 4]]}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM