递归就是调用自身,本质上是一个循环,循环终止的条件就是递归的出口
def f(i):
if i == 1:
return 1
return i + f(i -1)
result = f(999)
print(result)
结果为:RecursionError: maximum recursion depth exceeded in comparison
出现异常,提示程序超过最大递归深度,在Python3中,默认的堆栈大小为998
方法一:通过调用sys.setrecursionlimit调整栈的大小可解决这个问题
import sys
sys.setrecursionlimit(2000)
def f(i):
if i == 1:
return 1
return i + f(i -1)
result = f(999)
print(result)
结果为:499500
如果将“999”改为“2001”,还是会出发堆栈溢出的异常
方法二:使用“尾递归+生成器”彻底解决堆栈溢出
尾递归是指在返回时,仅调用自身,不包含其他运算式,如加减乘除等,同时使用“yield”关键字返回生成器对象
import types
def f_recursive(cur_i, cur_computer_result=1):
if cur_i == 1:
yield cur_computer_result
yield f_recursive(cur_i - 1, cur_i + cur_computer_result)
def f_recursive_wapper(generator, i):
gen = generator(i)
while isinstance(gen, types.GeneratorType):
gen = gen.__next__()
return gen
print(f_recursive_wapper(f_recursive,10000))
结果为:50005000
f_recursive函数体内使用yield返回时(此时该函数变成了生成器),返回的是这个函数本身,而不是一个具体的值编译器,对尾递归进行优化,不论递归调用多少次,都使用一个函数栈,即可避免堆栈的溢出