Applying `functools.lru_cache` to lambda

2020-07-09 10:36发布

So I made a recursive lambda in Python for the Fibonacci sequence. I used recursion because it was easiest to implement with lambda.

fib = lambda n: fib(n - 1) + fib(n - 2) if n > 1 else 1

Because using recursion, the same Fibonacci values were calculated many times, I thought using a cache decorator would help, and I knew that functools.lru_cache was an easy option.

I know you can't apply the decorator to the function using @functools.lru_cache to a lambda like a normal function, but when I tried this:

fib = functools.lru_cache((lambda n: fib(n - 1) + fib(n - 2) if n > 1 else 1), maxsize = None)

I got an error saying that functools.lru_cache wouldn't accept a function object as an argument.

>>> fib = functools.lru_cache((lambda n: fib(n - 1) + fib(n - 2) if n > 1 else 1), maxsize = None)
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    fib = functools.lru_cache((lambda n: fib(n - 1) + fib(n - 2) if n > 1 else 1), maxsize = None)
TypeError: lru_cache() got multiple values for argument 'maxsize'

I checked the docs, and it looks like functools.lru_cache only accepts a maxsize and a typed argument, which default to 128 and False respectively.

Is there a cleverer way to assign the decorator to the function rather than just defining the function without lambda and then applying the decorator?

2条回答
做个烂人
2楼-- · 2020-07-09 10:52

a small example with the most stupid function i could think of:

from functools import lru_cache

@lru_cache(maxsize=32)
def identity(x):
    return x

identity2 = lru_cache(maxsize=32)(lambda x: x)

the first version is the decorator version where you can see the first agument of lru_cache. from there it is easy to see how to get the syntax for a lambda expression right.

查看更多
beautiful°
3楼-- · 2020-07-09 11:05

Try fib = functools.lru_cache()(lambda n: fib(n - 1) + fib(n - 2) if n > 1 else 1)

I believe that calling lru_cache returns a function, which takes a function and returns a function. To supply a max size, use fib = functools.lru_cache(100)(lambda n: fib(n - 1) + fib(n - 2) if n > 1 else 1)

查看更多
登录 后发表回答