首先看两段代码
代码1
1
2
3
4
5
6
7
8
| def recursion_wrong(n):
if n == 1:
return n
else:
n -= 1
recursion_wrong(n)
print(recursion_wrong(10)) |
def recursion_wrong(n):
if n == 1:
return n
else:
n -= 1
recursion_wrong(n)
print(recursion_wrong(10))
结果为None
代码2
1
2
3
4
5
6
7
8
| def recursion_correct(n):
if n == 1:
return n
else:
n -= 1
return recursion_correct(n)
print(recursion_correct(10)) |
def recursion_correct(n):
if n == 1:
return n
else:
n -= 1
return recursion_correct(n)
print(recursion_correct(10))
结果为1
这是一个非常简单的递归程序,判断输入的n是否为1,如果不是,就继续判断n-1。直到n=1时,输出。
乍一看,似乎第一段代码没有什么问题。然而实际运行时,发现不论输入的值是多少,一定会返回None。必须要在调用自己的部分,加上return,才能得到自己想要的结果。
那么这是为什么呢?其实道理很简单。函数在执行时,递归到最内层的函数满足if条件,确实可以运算出结果,但此结果是最内层函数的结果而非最外层函数的结果。当这个运算结果一层一层返回到最外一层时,由于else语句中不包含return,此函数就会因执行完毕而返回None。因此递归函数的递归部分必须要加上return才可以。
或者换一种思路考虑。仅看代码1,看一下代码实际走的流程。假如输入n=10。明显if条件不满足,继续执行else语句。可以看到,else语句块不包含return语句,也就是说不论else内部语句如何执行,函数最终也只能返回None。除非在else语句块中有全局变量,否则其中的任何运算结果都是无法返回到函数之外的。
结论:递归函数的两个出口都需要有return才可以正常运行。
=========================================================================================================================================
2017.11.16更新
之前的思路欠妥。若递归函数内部包含全局变量,可以记录每次递归所修改的内容,那么递归的部分不加return也是可以了。关键是要看递归函数的作用是修改某个变量(列表,字典….)还是要输出某个结果。若要输出,则必须确保每次递归的结果都能传递到上一层,且上一层可以记录下来并继续向上传递。