如何制作与索引无关的2元组?

时间:2019-01-08 17:50:53

标签: python tuples memoization

我正在实现一个带有2个参数的函数,并缓存结果以提高性能(“备忘”技术)。但是我看到缓存功能重复。例如:

@memoize
def fn(a,b):
    #do something.

问题是我事先知道fn(a,b) == fn(b,a),所以我希望了解在这种情况下参数元组(a,b)等效于(b,a),但是目前此功能将它们缓存为2个单独的条目。

我是否需要为此目的开设一门新课,或者还有其他更优雅的方法吗?尽管我知道我可以为两个元组缓存相同的函数返回值,但是我真的很想知道如何实现“与索引无关”的元组。

此记忆代码仅是示例,我希望元组对象具有极高的通用性,也可以在其他情况下使用。

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之后)。