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

我发现从人的角度来看,以最少的代码解决最复杂的问题的思维方式应该是递归,无论是以前接触到的经典的斐波拉契函数还是最近研究的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))

 

posted @ 2014-02-22 23:29  LisPythoniC  阅读(839)  评论(0编辑  收藏  举报