为了账号安全,请及时绑定邮箱和手机立即绑定

在python中缓存函数的最后k个结果

在python中缓存函数的最后k个结果

慕少森 2021-09-11 15:55:28
我想编写一个函数,它接受一个单参数函数 f 和一个整数 k,并返回一个行为与 f 相同的函数,除了它缓存 f 的最后 k 个结果。例如,如果 memoize 是我们所追求的函数,并且让 mem_f = memoize(f, 2),那么:    mem_f(arg1) -> f(arg1) is computed and cached      mem_f(arg1) -> f(arg1) is returned from cache      mem_f(arg2) -> f(arg2) is computed and cached      mem_f(arg3) -> f(arg3) is computed and cached, and f(arg1) is evicted我所做的是:def memoize(f,k):    cache = dict()    def mem_f(*args):        if args in cache:            return cache[args]        result = f(*args)        cache[args]= result        return result     return mem_f该函数从缓存中返回结果,如果它不在缓存中,则计算并缓存它。但是,我不清楚如何只缓存 f 的最后 k 个结果?我是新手,任何帮助将不胜感激。
查看完整描述

3 回答

?
浮云间

TA贡献1829条经验 获得超4个赞

你可以functools.lru_cache用来做缓存。我接受一个maxsize参数来控制它缓存的数量:


from functools import lru_cache


@lru_cache(maxsize=2)

def test(n):

    print("calling function")

    return n * 2


print(test(2))

print(test(2))

print(test(3))

print(test(3))

print(test(4))

print(test(4))

print(test(2))

结果:


调用函数

4

4

调用函数

6

6

调用函数

8

8

调用函数

4


查看完整回答
反对 回复 2021-09-11
?
萧十郎

TA贡献1815条经验 获得超13个赞

解决方案

您可以使用以下方法修复您拥有的代码OrderedDict:


from collections import OrderedDict


def memoize(f, k):

    cache = OrderedDict()


    def mem_f(*args):

        if args in cache:

            return cache[args]

        result = f(*args)

        if len(cache) >= k:

            cache.popitem(last=False)

        cache[args]= result

        return result 

    return mem_f,cache

测试一下

def mysum(a, b):

    return a + b


mysum_cached,cache = memoize(mysum, 10)

for i in range(100)

    mysum_cached(i, i)


print(cache)

输出:


OrderedDict([((90, 90), 180), ((91, 91), 182), ((92, 92), 184), ((93, 93), 186), ((94, 94), 188), ((95, 95), 190), ((96, 96), 192), ((97, 97), 194), ((98, 98), 196), ((99, 99), 198)])

此版本memoize可能适用于您自己的代码。但是,对于生产代码(即其他人必须依赖的代码),您可能应该使用functools.lru_cacheMark Meyer 建议的标准库函数 ( )。


查看完整回答
反对 回复 2021-09-11
?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

扩展 Mark Meyer 的绝妙建议,以下是解决方案的使用方式lru_cache和问题的术语:


from functools import lru_cache



def memoize(f, k):

    mem_f = lru_cache(maxsize=k)(f)

    return mem_f



def multiply(a, b):

    print("Called with {}, {}".format(a, b))

    return a * b



def main():

    memo_multiply = memoize(multiply, 2)

    print("Answer: {}".format(memo_multiply(3, 4)))

    print("Answer: {}".format(memo_multiply(3, 4)))

    print("Answer: {}".format(memo_multiply(3, 7)))

    print("Answer: {}".format(memo_multiply(3, 8)))



if __name__ == "__main__":

    main()

结果:


Called with 3, 4

Answer: 12

Answer: 12

Called with 3, 7

Answer: 21

Called with 3, 8

Answer: 24


查看完整回答
反对 回复 2021-09-11
  • 3 回答
  • 0 关注
  • 229 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号