python中尾递归用法实例详解


Posted in Python onApril 28, 2015

本文实例讲述了python中尾递归用法。分享给大家供大家参考。具体分析如下:

如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。尾递归函数的特点是在回归过程中不用做任何操作,这个特性很重要,因为大多数现代的编译器会利用这种特点自动生成优化的代码。

原理:

当编译器检测到一个函数调用是尾递归的时候,它就覆盖当前的活跃记录而不是在栈中去创建一个新的。编译器可以做到这点,因为递归调用是当前活跃期内最后一条待执行的语句,于是当这个调用返回时栈帧中并没有其他事情可做,因此也就没有保存栈帧的必要了。通过覆盖当前的栈帧而不是在其之上重新添加一个,这样所使用的栈空间就大大缩减了,这使得实际的运行效率会变得更高。因此,只要有可能我们就需要将递归函数写成尾递归的形式.

代码:

# 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 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
@tail_call_optimized
def 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_optimized
def 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.

希望本文所述对大家的Python程序设计有所帮助。

Python 相关文章推荐
Python文件去除注释的方法
May 25 Python
Win10下Python环境搭建与配置教程
Nov 18 Python
Python判断变量是否为Json格式的字符串示例
May 03 Python
在matplotlib的图中设置中文标签的方法
Dec 13 Python
Python3解释器知识点总结
Feb 19 Python
python如何实现视频转代码视频
Jun 17 Python
Pytorch中.new()的作用详解
Feb 18 Python
Python post请求实现代码实例
Feb 28 Python
Python try except异常捕获机制原理解析
Apr 18 Python
python中sort sorted reverse reversed函数的区别说明
May 11 Python
Pytorch框架实现mnist手写库识别(与tensorflow对比)
Jul 20 Python
FP-growth算法发现频繁项集——构建FP树
Jun 24 Python
在Python中使用元类的教程
Apr 28 #Python
python删除列表中重复记录的方法
Apr 28 #Python
python3实现短网址和数字相互转换的方法
Apr 28 #Python
python实现从网络下载文件并获得文件大小及类型的方法
Apr 28 #Python
浅析Python中的多重继承
Apr 28 #Python
python输出当前目录下index.html文件路径的方法
Apr 28 #Python
Python实现基于权重的随机数2种方法
Apr 28 #Python
You might like
php xfocus防注入资料
2008/04/27 PHP
PHP查询数据库中满足条件的记录条数(两种实现方法)
2013/01/29 PHP
PHP之短标签开启设置
2013/06/17 PHP
PHP实现超简单的SSL加密解密、验证及签名的方法示例
2017/08/28 PHP
JavaScript匿名函数之模仿块级作用域
2015/12/12 Javascript
详解Javascript事件驱动编程
2016/01/03 Javascript
JS清除字符串中重复值的实现方法
2016/08/03 Javascript
javascript跨域请求包装函数与用法示例
2016/11/03 Javascript
基于BootstrapValidator的Form表单验证(24)
2016/12/12 Javascript
vue中组件的3种使用方式详解
2019/03/23 Javascript
详解vue 2.6 中 slot 的新用法
2019/07/09 Javascript
ElementUI中el-tree节点的操作的实现
2020/02/27 Javascript
在vue中使用Echarts利用watch做动态数据渲染操作
2020/07/20 Javascript
Django框架下在视图中使用模版的方法
2015/07/16 Python
Python3安装Pymongo详细步骤
2017/05/26 Python
python随机取list中的元素方法
2018/04/08 Python
Python中实例化class的执行顺序示例详解
2018/10/14 Python
flask框架渲染Jinja模板与传入模板变量操作详解
2020/01/25 Python
Python实现括号匹配方法详解
2020/02/10 Python
python操作docx写入内容,并控制文本的字体颜色
2020/02/13 Python
keras分类之二分类实例(Cat and dog)
2020/07/09 Python
canvas 绘图时位置偏离的问题解决
2020/09/16 HTML / CSS
输入N,打印N*N矩阵
2012/02/20 面试题
经贸韩语专业大学生职业规划
2014/02/14 职场文书
学校做一个有道德的人活动方案
2014/08/23 职场文书
张家口市高新区党工委群众路线教育实践活动整改方案
2014/10/25 职场文书
2014年工程师工作总结
2014/11/25 职场文书
2015年民主生活会发言材料
2014/12/15 职场文书
2015年信访工作总结
2015/04/07 职场文书
大学生敬老院活动总结
2015/05/07 职场文书
单位工资证明范本
2015/06/12 职场文书
小学课改工作总结
2015/08/13 职场文书
小学校园广播稿
2015/08/18 职场文书
科普 | 业余无线电知识-波段篇
2022/02/18 无线电
python前后端自定义分页器
2022/04/13 Python
Ubuntu18.04下QT开发Android无法连接设备问题解决实现
2022/06/01 Java/Android