向我解释尾调用优化的重要性以及Python需要它的原因

时间:2009-05-20 21:55:07

标签: python tail-recursion tail-call-optimization

显然,对于Python是否需要尾调用优化存在很大的争议。当有人shipped Guido a copy of SICP因为他没有“得到它”时,这就成了头。我和Guido在同一条船上。我理解尾调用优化的概念。我真的想不出为什么Python真正需要它。

为了让我更容易理解,有人可以给我一些使用TCO大大简化的代码片段吗?

5 个答案:

答案 0 :(得分:14)

就个人而言,我非常重视尾部呼叫优化;但主要是因为它使递归与迭代一样有效(或使迭代成为递归的子集)。在简约语言中,您可以在不牺牲性能的情况下获得巨大的表现力。

对于'实用'语言(如Python),OTOH,你通常会为几乎所有可以想象的情况提供很多其他结构,所以它不那么重要。当然,总是一件好事,允许无法预料的情况

答案 1 :(得分:6)

如果您非常希望将递归用于可能表示为循环的事物,那么“尾部调用优化”确实是必须的。然而,Guido,Python的仁慈独裁者(BDFL),坚信循环被表示为循环 - 因此他不会进行特殊情况的尾调用(牺牲堆栈跟踪转储和调试规则性)。

答案 2 :(得分:5)

Tail call optimization可以更轻松地编写递归函数而无需担心堆栈溢出:

def fac(n, result=1):
        if n > 1:
                return fac(n - 1, n * result)
        return result

如果没有尾调用优化,使用大数字调用它可能会溢出堆栈。

答案 3 :(得分:2)

我多年来一直在思考你的问题(信不信由你......)。我对这个问题投入如此深刻,以至于我最后写了一篇文章(这也是我几个月前写的一个模块的演示文稿,没有花时间写出如何做的精确解释)。如果您仍对此问题感兴趣,请在我的blog上阅读我的回答。用两个词来说明我tco模块的介绍;如果没有尾递归消除,你将找不到任何你已经做过的事情,但你可能会对我的想法感兴趣。

我知道纯粹的链接不是Stackoverflow的首选用法;但请考虑我写了一篇完整的文章来回答这篇文章(我在文章正文中提到),还包括一些用于说明它的图片。出于这个原因,我在这里发布这个不寻常的答案。

答案 4 :(得分:1)

Guido在后续post中认识到,TCO允许更清洁地将状态机的实现作为递归调用彼此的函数集合。然而,在同一篇文章中,他提出了一种没有TCO的替代同样更清洁的解决方案。