我正在实现一个带有2个参数的函数,并缓存结果以提高性能(“备忘”技术)。但是我看到缓存功能重复。例如:
@memoize
def fn(a,b):
#do something.
问题是我事先知道fn(a,b) == fn(b,a)
,所以我希望了解在这种情况下参数元组(a,b)
等效于(b,a)
,但是目前此功能将它们缓存为2个单独的条目。
我是否需要为此目的开设一门新课,或者还有其他更优雅的方法吗?尽管我知道我可以为两个元组缓存相同的函数返回值,但是我真的很想知道如何实现“与索引无关”的元组。
此记忆代码仅是示例,我希望元组对象具有极高的通用性,也可以在其他情况下使用。
答案 0 :(得分:2)
您可以将其分为两个功能。公共函数以任何顺序获取参数,并使用已排序的参数调用内部函数。内部功能是带有缓存的功能。
def fn(*args):
return cached_fn(*sorted(args))
@memoize
def cached_fn(*args)
# do something
这是一个时空折衷方案-为了将缓存的大小减小一半,需要进行一些额外的函数调用。希望您没有真正带有较长参数列表的函数,因此排序不应增加太多开销。
此解决方案要求参数的数据类型具有比较功能,以便可以对它们进行排序。没有这样的先决条件,我想不出一种通用的编写方法。处理某些类型时,您可以设计一个自定义方法来规范化订单。或者,您也许可以在缓存中使用自己的哈希函数,并使其与顺序无关。
答案 1 :(得分:1)
如果您想要一个非常通用的解决方案,不仅对于两个参数,而且可能对多个参数(其中(a, b, a)
与(a, a, b)
相同,但与(a, b, b)
不同),可以使用frozenset(Counter(argument_tuple).items())
计算每个值的出现次数,并将结果字典转换为冻结的元组集(在from collections import Counter
之后)。