Python 在尾部递归中重用先前分配的空间

Python 在尾部递归中重用先前分配的空间,python,recursion,Python,Recursion,我正在从中读取尾部递归 它声明python不支持尾部递归优化 尾部递归函数可以作为非尾部递归函数执行,即使用成堆的调用堆栈,而不会影响结果。通常,编译器识别尾部递归模式,并优化其执行。但是,并非所有编程语言都支持这种优化。例如,C、C++支持尾递归函数的优化。另一方面,Java和Python不支持尾部递归优化 我不明白尾部递归优化是什么意思 本教程提供了一个示例 def sum_non_tail_递归(ls): """ :类型ls:List[int] :rtype:int,输入列表的总和。 ""

我正在从中读取尾部递归

它声明python不支持尾部递归优化

尾部递归函数可以作为非尾部递归函数执行,即使用成堆的调用堆栈,而不会影响结果。通常,编译器识别尾部递归模式,并优化其执行。但是,并非所有编程语言都支持这种优化。例如,C、C++支持尾递归函数的优化。另一方面,Java和Python不支持尾部递归优化

我不明白
尾部递归优化
是什么意思

本教程提供了一个示例

def sum_non_tail_递归(ls):
"""
:类型ls:List[int]
:rtype:int,输入列表的总和。
"""
如果len(ls)==0:
返回0
#不是尾部递归,因为它在递归调用返回后进行一些计算。
返回ls[0]+和非尾递归(ls[1:])
定义和尾递归(ls):
"""
:类型ls:List[int]
:rtype:int,输入列表的总和。
"""
def助手(ls、acc):
如果len(ls)==0:
返回acc
#这是尾部递归,因为最后一条指令是递归调用。
返回帮助程序(ls[1:],ls[0]+acc)
返回帮助程序(ls,0)
并举例说明

注意,在尾部递归中,我们知道一旦从递归调用返回,我们也将立即返回,因此我们可以跳过整个递归调用返回链,直接返回到原始调用方。这意味着对于所有递归调用,我们根本不需要调用堆栈,这节省了我们的空间

例如,在步骤(1)中,堆栈中的空间将分配给
f(x1)
,以便调用
f(x2)
。然后在步骤(2)中,函数
f(x2)
将递归调用
f(x3)
。但是,系统不需要在堆栈上分配新的空间,而是可以简单地重用先前为第二次递归调用分配的空间。最后,在函数
f(x3)
中,我们到达了基本情况,函数可以简单地将结果返回给原始调用方,而不必返回到以前的函数调用

这里的关键思想是,我们可以跳过整个递归调用链,重用先前分配的空间

至于python,它不支持尾部递归优化


这是否意味着python仍然需要调用堆栈,并且不在尾部递归中重用先前分配的空间?

据我所知,是的,python将在堆栈中存储所有调用,即使函数可以优化为基本上是迭代的,但是我是谁呢?我想在这里可以找到一个很好的答案:为了跟踪递归来工作,函数的最后一个表达式需要调用另一个函数,其中所有参数都已经满足。这意味着调用者没有更多的事情要做,想象一下像这样的
def foo():return bar()
;调用
bar
时,
foo
上没有任何操作。因此,在本例中,解释器/编译器/任何东西都可以跳转到下一个函数,而不是创建新的堆栈帧。这使得实现无限递归成为可能谢谢你。尾部递归令人惊讶,它产生了一种错觉,程序员可以立即跳转到最终的基本情况,而无需任何中间步骤@我希望有一天我们能用python实现TCO!据我所知,是的,python会将所有调用存储在一个堆栈中,即使函数可以优化为本质上是迭代的,但我是谁。我认为在这里可以找到一个很好的答案:为了跟踪递归以工作,函数的最后一个表达式需要是对另一个函数的调用,其中所有参数都已经满足。这意味着调用者没有更多的事情要做,想象一下像这样的
def foo():return bar()
;调用
bar
时,
foo
上没有任何操作。因此,在本例中,解释器/编译器/任何东西都可以跳转到下一个函数,而不是创建新的堆栈帧。这使得实现无限递归成为可能谢谢你。尾部递归令人惊讶,它产生了一种错觉,程序员可以立即跳转到最终的基本情况,而无需任何中间步骤@我希望有一天我们能用python实现TCO!