如何制作索引不可知的二元组?
How to make an index-agnostic 2-tuple?
我正在实现一个带有 2 个参数的函数并缓存结果以提高性能("Memoization" 技术)。但是我在缓存功能中看到了重复。例如:
@memoize
def fn(a,b):
#do something.
问题是我事先知道fn(a,b) == fn(b,a)
,所以我希望它理解参数元组(a,b)
在这种情况下等同于(b,a)
,但是这个函数目前将它们缓存为 2 个单独的条目。
我需要为此目的制作一个新的 class 还是有其他更优雅的方法?虽然我知道我可以为两个元组缓存相同的函数 return 值,但我真的很想知道如何实现 "index-agnostic" 元组。
这个记忆代码只是一个例子,我希望我的元组对象非常通用,也可以在其他情况下使用。
如果您想要一个非常通用的解决方案,不仅针对两个参数,而且可能针对多个参数,其中 (a, b, a)
与 (a, a, b)
的处理方式相同,但与 (a, b, b)
的处理方式不同,您可以使用 frozenset(Counter(argument_tuple).items())
来计算每个值的出现次数,并将生成的 dict 转换为冻结的元组集(在 from collections import Counter
之后)。
您可以将其拆分为两个函数。 public 函数以任意顺序接受参数,并调用一个内部函数,并将参数排序。内部函数是带缓存的那个。
def fn(*args):
return cached_fn(*sorted(args))
@memoize
def cached_fn(*args)
# do something
这是一个时间-space 权衡 -- 有一些额外的函数调用是为了将缓存的大小减半。希望您没有带有很长参数列表的函数,因此排序不应增加太多开销。
此解决方案要求参数的数据类型具有比较功能,以便对它们进行排序。如果没有这样的先决条件,我想不出一种通用的方式来写这个。在处理某些类型时,您可以设计一种自定义方法来规范化订单。或者您可以在缓存中使用您自己的哈希函数,并使其与顺序无关。
我正在实现一个带有 2 个参数的函数并缓存结果以提高性能("Memoization" 技术)。但是我在缓存功能中看到了重复。例如:
@memoize
def fn(a,b):
#do something.
问题是我事先知道fn(a,b) == fn(b,a)
,所以我希望它理解参数元组(a,b)
在这种情况下等同于(b,a)
,但是这个函数目前将它们缓存为 2 个单独的条目。
我需要为此目的制作一个新的 class 还是有其他更优雅的方法?虽然我知道我可以为两个元组缓存相同的函数 return 值,但我真的很想知道如何实现 "index-agnostic" 元组。
这个记忆代码只是一个例子,我希望我的元组对象非常通用,也可以在其他情况下使用。
如果您想要一个非常通用的解决方案,不仅针对两个参数,而且可能针对多个参数,其中 (a, b, a)
与 (a, a, b)
的处理方式相同,但与 (a, b, b)
的处理方式不同,您可以使用 frozenset(Counter(argument_tuple).items())
来计算每个值的出现次数,并将生成的 dict 转换为冻结的元组集(在 from collections import Counter
之后)。
您可以将其拆分为两个函数。 public 函数以任意顺序接受参数,并调用一个内部函数,并将参数排序。内部函数是带缓存的那个。
def fn(*args):
return cached_fn(*sorted(args))
@memoize
def cached_fn(*args)
# do something
这是一个时间-space 权衡 -- 有一些额外的函数调用是为了将缓存的大小减半。希望您没有带有很长参数列表的函数,因此排序不应增加太多开销。
此解决方案要求参数的数据类型具有比较功能,以便对它们进行排序。如果没有这样的先决条件,我想不出一种通用的方式来写这个。在处理某些类型时,您可以设计一种自定义方法来规范化订单。或者您可以在缓存中使用您自己的哈希函数,并使其与顺序无关。