一个很Cool的Idear->Python的尾递归优化
来源:互联网 发布:js如何给input赋值 编辑:程序博客网 时间:2024/04/30 14:23
一个很Cool的Idear->Python的尾递归优化
偶然在国外一个网站瞅到的,非常的酷,发出来共享一下。一般来说,Python和Java,C#一样是没有尾递归自动优化的能力的,递归调用受到调用栈长度的限制被广泛的诟病,但是这个狂人用一个匪夷所思的方法解决了这个问题并在Python上实现了,从此Python的递归调用再也不用受到调用栈长度的制约,太酷了。
首先我们还是从递归说起,之前我发过一篇 《浅谈递归过程以及递归的优化》其中用到了斐波那契数来作为例子.线性递归的算法由于太过一低效就被我们Pass掉了,我们先来看尾递过方式的调用:
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)</span>
这段程序我们来测试一下,调用 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 Fib
RuntimeError: maximum recursion depth exceeded
>>>
好了,现在我们来尾递归优化
我们给刚才的Fib函数增加一个Decorator,如下:
@tail_call_optimizeddef 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)
恩,就是这个@tail_call_optimized的装饰器 ,这个装饰器使Python神奇的打破了调用栈的限制。
这下即使我们Fib(20000),也能在780ms跑出结果(780ms是以前博文提到那台2000元的上网本跑出来的结果)
不卖关子了,下面我们来看看这段神奇的代码:
import sys class TailRecurseException: def __init__(self, args, kwargs): self.args = args self.kwargs = kwargs def tail_call_optimized(g): """ This function decorates a function with tail call optimization. It does this by throwing an exception if it is it's own grandparent, and catching such exceptions to fake the tail call optimization. This function fails if the decorated function recurses in a non-tail context. """ def func(*args, **kwargs): f = sys._getframe() if f.f_back and f.f_back.f_back and f.f_back.f_back.f_code == f.f_code: raise TailRecurseException(args, kwargs) else: while 1: try: return g(*args, **kwargs) except TailRecurseException, e: args = e.args kwargs = e.kwargs func.__doc__ = g.__doc__ return func
转载于: http://www.cnblogs.com/Alexander-Lee/archive/2010/09/16/1827587.html
- 一个很Cool的Idear->Python的尾递归优化
- 【Python学习笔记】一个很酷的尾递归优化
- 一个很COOL的层窗体
- 一个很Cool的JS菜单效果
- idear开发工具的快捷键
- python递归函数的优化
- 一个很Cool的JS菜单效果(类似flash)
- 一个很COOL的图片验证码程序[含源码]
- 一个很久以前写的 Cool Buttons 脚本
- 一种很Cool的语言
- Python 尾递归优化
- js递归的优化(尾递归)
- 【No8.】ViewHolder的再次简化、优化写法 Cool!
- Flex中给Tool tips添加一个很Cool的动画特效的例子源码
- 很cool 很有意思的js代码
- sometips两个很cool的bat脚本
- 很cool的下拉菜单效果--层
- rails 几个很cool的插件
- Navicat for MySQL破解工具及操作
- 求10000内的质数
- 斐波那契数列谈矩阵(2)
- Android 屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最佳方案
- uva 10765 Doves and bombs(双联通分量)
- 一个很Cool的Idear->Python的尾递归优化
- 关于数据结构重要性的解释
- UML关系图
- ibatis/mybatis
- Longest Substring Without Repeating Characters
- online_judge_1074
- QSslSocket: cannot resolve SSLv2_client_method
- 814-The Letter Carrier's Rounds【模拟、STL、被坑了】
- 宇宙本源论