I want to write a function that accepts a single-argument function f, and an integer k, and returns a function that behaves the same as f except it caches the last k results of f.
For instance, if memoize is the function we're after, and let mem_f = memoize(f, 2), then:
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
What I have done is:
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
This function returns the result from cache and if it is not in cache, it is computed and cached. However, I am not clear how to cache only last k results of f? I am newbie, any help would be appreciated.
You could just use functools.lru_cache to do the caching. I accepts a maxsize parameter to control how much it caches:
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))
results:
calling function
4
4
calling function
6
6
calling function
8
8
calling function
4
Expanding on the excellent suggestion of Mark Meyer, here's what the solution looks like using lru_cache and the terminology of your question:
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()
Result:
Called with 3, 4
Answer: 12
Answer: 12
Called with 3, 7
Answer: 21
Called with 3, 8
Answer: 24
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With