为什么此代码的行为类似于尾递归

时间:2019-06-13 19:00:13

标签: python recursion tree

我正在编写此代码以通过有序和后序遍历创建二叉树,但我偶然发现了一个令人困惑的递归解决方案,因为该程序的行为就像是尾递归调用,而不是标准递归。

我已经将代码转换为通用代码,以便每个人都更容易理解

class Test:
    def func(self, array):      
        if not array:
            return 0
        print(array)
        array.pop(0)
        temp1 = self.func(array)
        temp2 = self.func(array)

x = [1,2,3,4,5,6]
temp = Test()
temp.func(x)    

我希望2个函数调用具有两次相同的输出。那是第一个调用应该导致[2,3,4,5,6],[3,4,5,6] ... [6]。第二个函数调用应该执行相同的操作。而是,第二次调用导致什么都没有发生。递归堆栈不应该保存数组的当前状态,为什么要更新它?

3 个答案:

答案 0 :(得分:3)

列表是可变的。在递归调用中,您传递列表,而在函数主体中,您对列表进行了突变。每个电话都在改变列表。递归堆栈不应“保持数组的当前状态”

答案 1 :(得分:2)

array是一个列表,一个可变对象。因此,func正在直接引用原始文件,而不是本地副本。在func中所做的更改是对该原始文件进行的。

答案 2 :(得分:0)

第二个调用不产生任何输出的原因是由于上一行的递归调用。到调用[]时,数组的值为temp2,因为在这种情况下列表是可变的。

temp1 = self.func(array)将产生以下输出:

>>> temp.func(x)
[1, 2, 3, 4, 5, 6]
[2, 3, 4, 5, 6]
[3, 4, 5, 6]
[4, 5, 6]
[5, 6]
[6]

此功能完成后,列表已被更改,array的值现在为[]。您可能需要在对列表执行任何更改之前创建列表的深层副本。