比较超过最大递归深度

Posted

技术标签:

【中文标题】比较超过最大递归深度【英文标题】:maximum recursion depth exceeded in comparison 【发布时间】:2013-11-30 18:58:45 【问题描述】:

我写了这段代码来计算组合的数量:

def fact(n):
    return 1 if(n == 1) else n * fact(n - 1)

def combinations(n,k):
    return fact(n)/((fact(n - k) * fact(k)))

while(True):
    print(combinations(int(input()), int(input())))

阶乘函数似乎工作正常。但是,当我尝试查找两个数字的组合时,为什么它会给我一个超出比较错误的最大递归深度呢?阶乘函数是否有问题,因为这似乎是错误的来源?

这是我得到的错误:

builtins.RuntimeError:比较中超出了最大递归深度

【问题讨论】:

math.factorial有什么问题吗? scipy.misc.comb 有什么问题? 【参考方案1】:

对于像阶乘这样的简单函数,您应该尽量避免递归。递归确实很强大,但有时会无缘无故地被过度使用。

下面是阶乘函数迭代版本的代码:

def fact(n):
    result = 1
    for i in range(2, n + 1):
        result *= i
    return result

请注意 Maxime 在上一个答案中所说的,这正是您遇到的问题:您的函数没有考虑 0 的阶乘。

【讨论】:

【参考方案2】:

尝试替换:

def fact(n):
    return 1 if(n == 1) else n * fact(n - 1)

到:

def fact(n):
    return 1 if(n <= 1) else n * fact(n - 1)

因为如果您传递 2 个相同的数字,您将尝试计算 fact(0)(这将调用 fact(-1)fact(-2) 等,直到最大递归深度错误)。

【讨论】:

【参考方案3】:

python 3.x 及以后的版本默认递归限制为 2000 次,如果你一次又一次地调用同一个函数超过 2000 次,你会得到最大递归深度错误。理想的方法是编写没有递归的逻辑。但如果您仍然坚持递归,请通过以下方式更改默认递归限制:

导入系统

sys.setrecursionlimit(10000)# 设置递归限制为10000。

但在某些情况下,上述内容可能无法满足您的所有需求。

【讨论】:

这里我们遇到了递归比较次数的问题。该限制远低于最大递归深度。【参考方案4】:

你的递归深度超出了限制。

    递归不是 Python 中最惯用的做事方式,因为它没有 tail recursion 优化,因此使用递归代替迭代是不切实际的(即使在您的示例中函数是不是尾递归,无论如何这都无济于事)。基本上,这意味着如果您希望输入很大,则不应将其用于复杂性大于线性的事物。

    如果你的平台支持更高的限制,你可以将限制设置得更高:

    sys.setrecursionlimit(some_number) sys.setrecursionlimit(some_number)

    此函数将 Python 解释器堆栈的最大深度设置为限制。此限制可防止无限递归导致 C 堆栈溢出和 Python 崩溃。可能的最高限制取决于平台。当用户有一个需要深度递归的程序和一个支持更高限制的平台时,她可能需要将限制设置得更高。这应该小心完成,因为过高的限制会导致崩溃。

参考:Python recursive function error: “maximum recursion depth exceeded”Python max recursion , question about sys.setrecursionlimit()

【讨论】:

【参考方案5】:
sys.setrecursionlimit(some_number)

【讨论】:

【参考方案6】:

这样的东西效果很好:

def factorial_by_recursion(max_number, current_number, somme):
    if current_number < max_number:
        somme += current_number
        return factorial_by_recursion(max_number, current_number + 1, somme)
    else:
        return somme

【讨论】:

以上是关于比较超过最大递归深度的主要内容,如果未能解决你的问题,请参考以下文章

RecursionError:比较超过最大递归深度

合并排序“比较超过最大递归深度” [重复]

Binary Search RecursionError:比较超过最大递归深度

超过最大递归深度 google colab

spark 提交 pyspark 脚本上的纱线投掷超过最大递归深度

超过了 Django 最大递归深度。无限查看循环