当前位置: 首页 > 面试题库 >

为什么Python具有最大的递归深度?

濮阳振海
2023-03-14
问题内容

Python具有最大的递归深度,但没有最大的迭代深度。为什么限制递归?像迭代一样对待递归而不限制递归调用的数量会更自然吗?

让我只说这个问题的根源在于尝试实现流。例如,假设我们要编写一个流以产生自然数:

def stream_accum(s, n): # force the stream to a list of length n
    def loop(s, acc):
        if len(acc) == n:
            return acc
        hd, tl = s()
        return loop(tl, acc + [hd])
    return loop(s, [])


def nats():
    def loop(n):
        return n, lambda: loop(n+1)
    return loop(1)

流的递归定义非常吸引人。但是,我想更好/更多的pythonic方法是使用生成器。


问题答案:

实际上这里有一些问题。

首先,正如NPE的回答很好地说明的那样,Python不会消除尾部调用,因此许多允许进行无限递归的函数(例如Scheme)在Python中受到限制。

其次,正如NPE所解释的那样,无法消除的调用占用了调用堆栈上的空间。而且,即使在执行TCE的语言中,也有很多递归函数不能像迭代那样对待。(考虑一下朴素的Fibonacci函数,该函数递归调用两次。)

但是为什么调用栈首先是有限的资源呢?Python堆栈框架至少可以原则上在堆上实现并链接在一起(有关该原理的存在性证明,请参见Stackless),并且在64位内存空间中,可以容纳1000个以上的堆栈框架。(实际上,即使是几乎任何现代平台上的C堆栈,也都可以容纳1000多个递归Python解释器调用。)

部分原因是历史原因:当您进行递归调用时,现有的Python解释器使用固定的C堆栈来递归调用自身,它最初是为32位(甚至24位或20位)平台设计的,堆栈很小。

但这可能已经改变,Python
3.0将是更改它的理想场所。那么,为什么不呢?因为他们做出了自觉的语言设计决策。在Pythonic代码中,递归通常非常浅(例如,类似的代码os.walk会遍历浅树结构)。如果函数的深度达到1000左右,那么它很有可能是错误而不是有意的。因此,限制仍然存在。当然,这有点循环-
如果他们删除了限制(尤其是如果他们消除了尾部调用),则更深层次的递归将变得更加惯用。但这就是重点-
圭多(Guido)不需要一种习惯于深度递归的语言。(并且大多数Python社区都同意。)




 类似资料:
  • 问题内容: 有一个参数(默认值为9),该参数控制对内联的嵌套调用的最大数量。为什么会有这样的限制?为什么基于频率和代码大小的常规启发式方法不足以使JVM自行决定内联的深度? (这是由JitWatch提示的,向我显示了由于深度而未内嵌深层嵌套的Guava 调用) 问题答案: 一些重要的搜索发现了这个有趣的小片段(我实际上到达了Google搜索的第 4 页): 这表明,按预期的那样,硬限制是您停止内联

  • 我对Python很陌生。我写了一个关于返回 x 在排序的重复元素数组 A 中的出现次数的函数: 错误是:运行时错误:超出最大递归深度。有人知道如何解决它吗?

  • 问题内容: 我使用以下代码解决了Euler项目的问题10,该代码通过强力工作: 这三个功能的工作方式如下: isPrime 检查数字是否为质数; primeList 返回一个列表,其中包含一组在一定范围内且限制为“ n”的素数,并且; sumPrimes 对列表中所有数字的值求和。(不需要最后一个功能,但是我喜欢它的清晰度,特别是对于像我这样的初学者。) 然后,我编写了一个新函数 primeLis

  • 问题内容: 我决定尝试一些实验,以了解关于堆栈帧大小以及当前执行的代码在堆栈中的距离的发现。我们可能在这里调查两个有趣的问题: 当前代码有多少层深入堆栈? 当前方法在达到a之前可以达到多少级别的递归? 当前执行代码的堆栈深度 这是我为此能想到的最好的方法: 这似乎有点骇人听闻。它生成并捕获异常,然后查看堆栈跟踪的长度。 不幸的是,它似乎也有一个致命的限制,那就是返回的堆栈跟踪的最大长度为1024。

  • 问题内容: 我从星期一开始使用Python进行编程。我很喜欢学习它。但是我一直试图了解如何在tkinter菜单之间切换时避免递归!我确信这是一个非常基本的问题,感谢您宽容我对此主题的无知,但我无法在其他地方找到答案。 我现在正在做的最终是给我错误:RuntimeError:调用Python对象时超出了最大递归深度 这是我目前正在使用的模式。更新:下面的代码现在是完整的隔离副本,再现了我面临的问题!

  • 我正试图从ESPN那里获得一些票房成绩。com并将其放入Pandas DataFrame中。我过去也以同样的方式做过类似的事情,没有任何问题。然而,在这种情况下,当我试图保存DataFrame时,我遇到了这个错误。 RuntimeError:调用Python对象时超出最大递归深度 当我试图将它保存为hdf5表时,也出现了类似的错误。 即使这个代码片段也会给出相同的错误。我很困惑它为什么要这样做?与