Python递归函数问题



我是python初学者,目前我正在努力学习python递归函数:

x = 10
n = 3

def rec(x,n):
if n>0:
#global x2
x2 = x*n
return rec(x2,n-1)
else:
return x2
# function call:
fcall = rec(x,n)
print fcall

让我困惑的是global x2行。有了它,函数运行良好,按预期返回60,但没有它,我会收到一条错误消息:

Local variable 'x2' referenced before assignment

为什么会这样?似乎一旦n达到3的值,并且执行了else条件,它就不知道x2是什么?

如果省略global,则该变量应在该函数的本地范围内。这意味着它需要被分配到某个地方才能真正存在。由于唯一的赋值是当n > 0条件为true时,return x2将始终尝试返回一个不存在的变量。

当您添加global时,您将该变量放入全局范围,使其在任何地方都可用。因此,它被分配并可以返回。

然而,让函数依赖于这样的全局变量并不是一个好主意。似乎很不明显,它需要一个全局变量才能工作。事实上,这里没有必要:您希望引用x而不是x2

def rec (x, n):
if n > 0:
x = x * n
return rec(x, n - 1)
else:
return x

这样,只要n仍然大于零,就可以将当前x乘以n,并将其临时重新分配给x,然后将其传递给递归调用。如果n等于零,则适用else的情况,并且只返回传递给函数的当前x

您的问题是x2只是一个局部变量,所以当您调用函数时,它不再知道旧的x2。

通过添加全局x2,您可以将该变量放入全局空间,因此现在函数可以识别它。

看看这个:http://gettingstartedwithpython.blogspot.de/2012/05/variable-scope.html

您实际想要返回的是x,而不是x2,因为您正在将x2的值传递到递归的下一个调用中。

def rec(x,n):
if n>0:
x2 = x*n
return rec(x2,n-1)
else:
return x

如果没有global x2,分配给x2将创建一个新的局部变量。有了它,分配给x2会更改全局x2变量。这只适用于赋值,而不适用于查找变量。

当函数返回时,当前堆栈帧(以及与之相关的所有局部变量)将消失,但全局变量将永远存在(使用它们也会感到非常糟糕)。

您还可以将rec函数代码重构为:

def rec(x, n):
return rec(x*n, n-1) if n else x

对于初学者来说,问题的一个典型原因是使用过多变量的习惯。这会使事情变得更加复杂和难以理解。你的代码可以变得更简单,如下所示:

def rec(x, n):
if n > 0:
return rec(x*n, n-1)
return x

甚至是这样,使用三元运算符:

def rec(x, n):
return rec(x*n, n-1) if n > 0 else x

然后你可以尝试一下:

rec(3, 10)

你越早养成只在需要时创建新变量的习惯,或者提高代码的可读性,你的程序就越容易编写、调试和读取。

最新更新