时间:2021-05-22
尾递归简介
尾递归是函数返回最后一个操作是递归调用,则该函数是尾递归。
递归是线性的比如factorial函数每一次调用都会创建一个新的栈(last-in-first-out)通过不断的压栈,来创建递归, 很容易导致栈的溢出。而尾递归则使用当前栈通过数据覆盖来优化递归函数。
阶乘函数factorial, 通过把计算值传递的方法完成了尾递归。但是python不支出编译器优化尾递归所以当递归多次的话还是会报错(学习用)。
eg:
def factorial(n, x): if n == 0: return x else: return factorial(n-1, n*x)print factorial(5, 1) # 120尾递归优化
这里用到了斐波那契数来作为例子.线性递归的算法由于太过一低效就被我们Pass掉了,我们先来看尾递过方式的调用:
这段程序我们来测试一下,调用 Fib(1001)结果:
>>> def Fib(n,b1=1,b2=1,c=3):... if n<3:... return 1... else:... if n==c:... return b1+b2... else:... return Fib(n,b1=b2,b2=b1+b2,c=c+1)... >>> Fib(1001)70330367711422815821835254877183549770181269836358732742604905087154537118196933579742249494562611733487750449241765991088186363265450223647106012053374121273867339111198139373125598767690091902245245323403501L>>>如果我们用Fib(1002),结果,茶几了,如下:
..... File "<stdin>", line 8, in Fib File "<stdin>", line 8, in Fib File "<stdin>", line 8, in Fib File "<stdin>", line 8, in Fib File "<stdin>", line 8, in Fib File "<stdin>", line 8, in FibRuntimeError: maximum recursion depth exceeded>>>好了,现在我们来尾递归优化
我们给刚才的Fib函数增加一个Decorator,如下:
恩,就是这个@tail_call_optimized的装饰器 ,这个装饰器使Python神奇的打破了调用栈的限制。
这下即使我们Fib(20000),也能在780ms跑出结果(780ms是以前博文提到那台2000元的上网本跑出来的结果)
不卖关子了,下面我们来看看这段神奇的代码:
使用的方法前面已经展示了,令我感到大开眼界的是,作者用了抛出异常然后自己捕获的方式来打破调用栈的增长,简直是太匪夷所思了。而且效率问题,和直接尾递归Fib相比大概造成了五倍的时间开销。
最后很不可思议的,尾递归优化的目的达成了。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了Python装饰器用法。分享给大家供大家参考,具体如下:下面的程序示例了python装饰器的使用:示例一:defouter(fun):printf
本文研究的主要是Python使用装饰器进行django开发的相关内容,具体如下。装饰器可以给一个函数,方法或类进行加工,添加额外的功能。在这篇中使用装饰器给页面
CPS:http://en.wikipedia.org/wiki/Continuation-passing_style示例代码使用迭代+尾递归。复制代码代码如下
Python装饰器语法糖代码示例####装饰器的固定格式##普通版本deftimer(func):definner(*args,**kwargs):'''执行函
本文主要介绍Python中,class(类)的装饰器@staticmethod和@classmethod的使用示例代码和它们的区别。1、@staticmetho