猿问

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

我想编写一个函数,它接受一个单参数函数 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 个结果?我是新手,任何帮助将不胜感激。


慕少森
浏览 230回答 3
3回答

浮云间

你可以functools.lru_cache用来做缓存。我接受一个maxsize参数来控制它缓存的数量:from functools import lru_cache@lru_cache(maxsize=2)def test(n):    print("calling function")    return n * 2print(test(2))print(test(2))print(test(3))print(test(3))print(test(4))print(test(4))print(test(2))结果:调用函数44调用函数66调用函数88调用函数4

萧十郎

解决方案您可以使用以下方法修复您拥有的代码OrderedDict:from collections import OrderedDictdef 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 + bmysum_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 建议的标准库函数 ( )。

一只名叫tom的猫

扩展 Mark Meyer 的绝妙建议,以下是解决方案的使用方式lru_cache和问题的术语:from functools import lru_cachedef memoize(f, k):    mem_f = lru_cache(maxsize=k)(f)    return mem_fdef multiply(a, b):    print("Called with {}, {}".format(a, b))    return a * bdef 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, 4Answer: 12Answer: 12Called with 3, 7Answer: 21Called with 3, 8Answer: 24
随时随地看视频慕课网APP

相关分类

Python
我要回答