python尾递归
来源:互联网 发布:查找iphone有网络离线 编辑:程序博客网 时间:2024/04/30 16:33
def fact(n): if n==1: return 1 return n * fact(n - 1)
使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。
>>> fact(1000)Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in fact ... File "<stdin>", line 4, in factRuntimeError: maximum recursion depth exceeded
解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。
尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。
def fact(n): return fact_iter(1, 1, n)def fact_iter(product, count, max): if count > max: return product return fact_iter(product * count, count + 1, max)
有一个针对尾递归优化的decorator,可以参考源码:
http://code.activestate.com/recipes/474088-tail-call-optimization-decorator/
#!/usr/bin/env python2.4# This program shows off a python decorator(# which implements tail call optimization. It# does this by throwing an exception if it is # it's own grandparent, and catching such # exceptions to recall the stack.import sysclass TailRecurseException: def __init__(self, args, kwargs): self.args = args self.kwargs = kwargsdef 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@tail_call_optimizeddef factorial(n, acc=1): "calculate a factorial" if n == 0: return acc return factorial(n-1, n*acc)print factorial(10000)# prints a big, big number,# but doesn't hit the recursion limit.@tail_call_optimizeddef fib(i, current = 0, next = 1): if i == 0: return current else: return fib(i - 1, next, current + next)print fib(10000)# also prints a big number,# but doesn't hit the recursion limit.
解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。
尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。
def fact(n): return fact_iter(1, 1, n)def fact_iter(product, count, max): if count > max: return product return fact_iter(product * count, count + 1, max)
0 0
- python 函数递归 尾递归
- Python 尾递归优化
- python 尾递归
- python尾递归
- Python尾递归
- python 实现尾递归
- Python尾递归
- python的递归函数--含尾递归
- 【Python学习日记】递归和尾递归 以及Python
- Python 与尾递归优化
- Python递归
- Python递归
- python递归
- Python | 递归
- Python 递归
- python 递归
- 递归与伪递归区别,Python 实现递归与尾递归
- python 斐波拉契递归 尾递归 备忘录 动态规划 迭代
- random 使用时需要sleep一下,否则每次的随机数是一样的
- Serlet ServletConfig对象
- 解决java.lang.IllegalArgumentException: Document base D:\jakarta-tomcat-5.0.28\webapps\BIDemo does not
- $* $@ $#各自的含义 区别
- JBPM5 安装配置和JBPM开发环境入门
- python尾递归
- 各种拨号接入方式简单总结
- Linux中find常见用法示例
- 学术写作利器——LaTeX入门
- 筛选法求素数
- flex总结
- 二叉树的遍历 递归 非递归 C++ 实现
- limeJS Demo学习
- 大数a^b%n模板