【问题标题】:How does Python handle infinite recursion?Python如何处理无限递归?
【发布时间】:2014-09-13 23:35:12
【问题描述】:

所以在玩 Python 时,我注意到程序的堆栈大小基本上没有限制(不断对数字执行幂运算,即使达到数千位数,精度也保持完美)。这让我想知道:如果我不小心进入了 Python 中的无限递归循环怎么办?编译器会注意到并抛出堆栈溢出错误吗?还是程序会崩溃?我的 CPU 会燃烧吗?老实说,这不是我急于测试自己的事情。

【问题讨论】:

标签: python recursion infinite


【解决方案1】:

我保证,现代计算机不会因为用户代码而燃烧。自己试试吧:

def recurseInfinitely( n ):
    recurseInfinitely(n+1)

recurseInfinitely(0)

运行这个程序会立即产生输出:

  [...]
    recurseInfinitely(n+1)
  File "so.py", line 2, in recurseInfinitely
    recurseInfinitely(n+1)
  File "so.py", line 2, in recurseInfinitely
    recurseInfinitely(n+1)
RuntimeError: maximum recursion depth exceeded   

您可以捕获错误并检查n的值:

def recurseInfinitely( n ):   
    try:
        recurseInfinitely(n+1)
    except RuntimeError:
        print "We got to level %s before hitting the recursion limit."%n

得到:

在达到递归限制之前,我们达到了 997 级。

【讨论】:

    【解决方案2】:

    Python(至少是参考实现)没有——你不能像某些函数式语言那样拥有无限递归循环。当递归达到大约 1000 深度时,它将抛出异常(默认情况下,可以使用 sys.setrecursionlimit 更改)。所以是的,程序会崩溃。

    与大多数函数式语言不同,Python 缺乏尾递归优化。我敢说,所有的递归算法都应该在 Python 中转换为迭代形式(这样做很简单),否则你的实现并不真正正确。

    用户 larsmans 评论说,内置递归深度限制对于大多数实用算法来说已经足够好了,但迭代形式通常表现得更好——原因是 Python 中的函数调用很昂贵。

    如果你循环一个从不抛出 StopIteration 的生成器,你可以在 Python 中有一个跑道循环。它会一直运行,直到(如果)您终止进程或耗尽计算机资源(有时会使机器停止运转)。

    【讨论】:

    • 在许多实际的递归算法中,递归深度与输入大小成对数(考虑排序、稳定和)。因此,对于 c 一个小常数,默认设置算法最多对 2**(1000-c) 个项目是正确的。这对我来说已经足够了。
    • 但是,如果您正在创建一个预计可以处理大量数据的库,那么迭代显然更好。一旦以递归方式实现,我就遇到了生物信息学库的问题。 >_
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多