[英]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.