# Python函数式编程系列004：递归

## 从递推说起

``````def power1(x: float, n: int) -> float:
res = 1
for i in range(n):
res *= x
return res``````

## 递归

``````def power2(x: float, n: int) -> float:
if n == 0:
return 1
else:
return x * power2(x, n - 1)``````

## 尾递归

``````power2(2.0, 5)
2.0 * power2(2.0, 4)
2.0 * (2.0 * power2(2.0, 3))
2.0 * (2.0 * (2.0 * power2(2.0, 2)))
2.0 * (2.0 * (2.0 * (2.0 * power2(2.0, 1))))
2.0 * (2.0 * (2.0 * (2.0 * (2.0 * power2(2.0, 0)))))
2.0 * (2.0 * (2.0 * (2.0 * (2.0 * 1.0))))
2.0 * (2.0 * (2.0 * (2.0 * 2.0)))
2.0 * (2.0 * (2.0 * 4.0))
2.0 * (2.0 * 8.0)
2.0 * 16.0
32.0``````

``````def power3(x: float, n: int, acc: float = 1.0) -> float:
if n == 0:
return acc
else:
return power3(x, n - 1, acc * x)``````

``````power3(2.0, 5, 1)
power3(2.0, 4, 1 * 2.0)
power3(2.0, 4, 2.0)
power3(2.0, 3, 2.0 * 2.0)
power3(2.0, 3, 4.0)
power3(2.0, 2, 4.0 * 2.0)
power3(2.0, 2, 8.0)
power3(2.0, 1, 8.0 * 2.0)
power3(2.0, 1, 16.0)
power3(2.0, 0, 16.0 * 2.0)
power3(2.0, 0, 32.0)
32.0``````

``````import inspect

def tail_rec(func):
rec_flag = False
targs = []
tkwargs = []
def helper(*args, **kwargs):
nonlocal rec_flag
nonlocal targs
nonlocal tkwargs
f = inspect.currentframe()

if  f.f_code == f.f_back.f_back.f_code:
rec_flag = True
targs = args
tkwargs = kwargs
return
else:
while True:
try:
result = func(*args, **kwargs)
except TypeError as e:
raise Exception("It is possible that the decorated function is not tail recursive")
if rec_flag:
rec_flag = False
args = targs
kwargs = tkwargs
else:
return result
return helper``````

``````@tail_rec
def power4(x: float, n: int, acc: float = 1.0):
if n == 0:
return acc
else:
return power4(x, n - 1, acc * x)``````

``````@tail_rec
def power5(x: float, n: int):
def helper(x: float, n: int, acc: float):
if n == 0:
return acc
else:
return helper(x, n - 1, acc * x)
return helper(x, n, 1.0)``````

``````>>> power5(2.0, 5)
32.0``````

0 条评论