将尾递归函数转换为迭代函数的利器

时间:2021-11-11 03:05:27

我发现从人的角度来看,以最少的代码解决最复杂的问题的思维方式应该是递归,无论是以前接触到的经典的斐波拉契函数还是最近研究的Hanoi变体-4柱最优步骤生成函数(注意,不仅仅是得出最小的步骤总数).

非线性递归---尾递归---迭代

遗憾的是,从右到左,对计算机是越来越不友好. 而从非线性递归转化为尾递归相对来说要容易一些, 如果有一个装饰器,它能够使所有尾递归函数自动变为等价的迭代函数,那么就相当于极大扩展了递归在Python的应用空间.

 

还真就有这种装饰器!今天无意发现的.

class TailRecursive(object):
"""
tail_recursive decorator based on Kay Schluehr's recipe
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496691
with improvements by me and George Sakkis.
"""

def __init__(self, func):
self.func
= func
self.firstcall
= True
self.CONTINUE
= object() # sentinel

def __call__(self, *args, **kwd):
CONTINUE
= self.CONTINUE
if self.firstcall:
func
= self.func
self.firstcall
= False
try:
while True:
result
= func(*args, **kwd)
if result is CONTINUE: # update arguments
args, kwd = self.argskwd
else: # last call
return result
finally:
self.firstcall
= True
else: # return the arguments of the tail call
self.argskwd = args, kwd
return CONTINUE

@TailRecursive
def factorial(n, acc=1):
"The good old factorial"
if n == 0: return acc
return factorial(n-1, n*acc)

def fac(n, acc=1):
"The good old factorial"
if n == 0: return acc
return fac(n-1, n*acc)

if __name__=='__main__':
for i in range(1,20):
print(fac(i)==factorial(i))