Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中缓存函数的最后k个结果_Python_Python 3.x_Function_Caching_Memoization - Fatal编程技术网

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

在python中缓存函数的最后k个结果,python,python-3.x,function,caching,memoization,Python,Python 3.x,Function,Caching,Memoization,我想写一个函数,它接受一个单参数函数f和一个整数k,并返回一个与f行为相同的函数,只是它缓存了f的最后k个结果 例如,如果memoize是我们要使用的函数,让mem_f=memoize(f,2),那么: 我所做的是: def memoize(f,k): cache = dict() def mem_f(*args): if args in cache: return cache[args] result = f(*args

我想写一个函数,它接受一个单参数函数f和一个整数k,并返回一个与f行为相同的函数,只是它缓存了f的最后k个结果

例如,如果memoize是我们要使用的函数,让mem_f=memoize(f,2),那么:

我所做的是:

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个结果?我是新手,希望您能提供帮助

解决方案 您可以通过如下方式使用
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
测试它 输出:

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
可能适用于您自己的代码。但是,对于生产代码(即其他人必须依赖的代码),您可能应该使用Mark Meyer建议的标准库函数(
functools.lru\u 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
调用函数
四,


扩展Mark Meyer的优秀建议,下面是使用
lru缓存的解决方案以及您问题的术语:

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

这将需要一个额外的数据结构来保持最后调用的键(=参数)。一个这样的结构可以是
collections.deque
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