Python 3.x &引用;超过最大递归深度;使用lru_缓存时

Python 3.x &引用;超过最大递归深度;使用lru_缓存时,python-3.x,caching,recursion,Python 3.x,Caching,Recursion,我想使用lru缓存计算递归函数。以下是它的简化版本: from functools import lru_cache @lru_cache(maxsize=None) def f(n:int)->int: if (n==0): return 1 return n+f(n-1) ### MAIN ### print(f(1000)) 当我运行f(100)时效果很好,但使用f(1000)时,我得到: 一种解决方案是为f自己计算一个值表。有没有一种解决方案不需要我手动创建一

我想使用lru缓存计算递归函数。以下是它的简化版本:

from functools import lru_cache

@lru_cache(maxsize=None)
def f(n:int)->int:
    if (n==0): return 1
    return n+f(n-1)

### MAIN ###
print(f(1000))
当我运行f(100)时效果很好,但使用f(1000)时,我得到:

一种解决方案是为f自己计算一个值表。有没有一种解决方案不需要我手动创建一个值表?

请注意,您可以按原样使用函数,但您需要确保每次新调用在命中缓存值或递归基本情况之前不必递归超过几百级;e、 g

>>> f(400)
80201
>>> f(800)  # will stop recursing at 400
320401
>>> f(1000) # will stop recursing at 800
500501
我有时会诉诸于此;-)更一般地说,您可以编写一个包装函数,反复尝试
f(n)
,捕获
RecursionError
,并放弃使用更小的
n
值调用它。比如说,

def superf(n, step=400):
    pending = []
    while True:
        pending.append(n)
        try:
            f(n)
            break
        except RecursionError:
            n = max(n - step, 0)
    while pending:
        x = f(pending.pop())
    return x
然后


这与
lru\u缓存
无关。Python只是在默认情况下将递归的深度限制为1000。可能的@hop重复-这不是重复。看看下面的答案。@hop,我怀疑有人在开玩笑;-)OP似乎是一位尝试了很多想法的博士生。递归函数在研究中通常非常自然,
@lru\u cache
可以极大地提高它们的速度。当它们在小案例中运行良好时,您需要将其推到更大的案例中。根据我的经验,大多数想法最终都失败了。我们的目标是编写评估“足够快”的想法所需的最少代码,而对一个明显的递归函数进行的每一次手工代码优化都有引入错误的风险。@TimPeters:我不反对你,但今天在这里没有学到任何东西。
def superf(n, step=400):
    pending = []
    while True:
        pending.append(n)
        try:
            f(n)
            break
        except RecursionError:
            n = max(n - step, 0)
    while pending:
        x = f(pending.pop())
    return x
>>> superf(100000)
5000050001