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 BeautifulSoup库抓取58手机维修信息
Nov 21 Python
Python使用代理抓取网站图片(多线程)
Mar 14 Python
跟老齐学Python之折腾一下目录
Oct 24 Python
Python数据类型详解(四)字典:dict
May 12 Python
Python中list查询及所需时间计算操作示例
Jun 21 Python
对python 通过ssh访问数据库的实例详解
Feb 19 Python
Python学习笔记之视频人脸检测识别实例教程
Mar 06 Python
python2和python3应该学哪个(python3.6与python3.7的选择)
Oct 01 Python
python3中的logging记录日志实现过程及封装成类的操作
May 12 Python
详解Python设计模式之策略模式
Jun 15 Python
Python字典取键、值对的方法步骤
Sep 30 Python
如何使用 Flask 做一个评论系统
Nov 27 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
常用星际术语索引(新手指南)
2020/03/04 星际争霸
php生成EAN_13标准条形码实例
2013/11/13 PHP
PHP+apc+ajax实现的ajax_upload上传进度条代码
2016/01/25 PHP
PHP模板引擎Smarty内置变量调解器用法详解
2016/04/11 PHP
PHP微商城开源代码实例
2019/03/27 PHP
thinkphp3.2同时连接两个数据库的简单方法
2019/08/13 PHP
php计数排序算法的实现代码(附四个实例代码)
2020/03/31 PHP
Prototype使用指南之selector.js
2007/01/10 Javascript
WordPress 照片lightbox效果的运用几点
2009/06/22 Javascript
浅谈JSON和JSONP区别及jQuery的ajax jsonp的使用
2014/11/23 Javascript
JS中的forEach、$.each、map方法推荐
2016/04/05 Javascript
基于JavaScript实现购物网站商品放大镜效果
2016/09/06 Javascript
Vue.js教程之计算属性
2016/11/11 Javascript
JS变量及其作用域
2017/03/29 Javascript
Vue计算属性的使用
2017/08/04 Javascript
js截取字符串功能的实现方法
2017/09/27 Javascript
promise和co搭配生成器函数方式解决js代码异步流程的比较
2018/05/25 Javascript
微信小程序实现注册登录功能(表单校验、错误提示)
2019/12/10 Javascript
Bootstrap简单实用的表单验证插件BootstrapValidator用法实例详解
2020/03/29 Javascript
python用字典统计单词或汉字词个数示例
2014/04/22 Python
Python通过websocket与js客户端通信示例分析
2014/06/25 Python
Python3 queue队列模块详细介绍
2018/01/05 Python
Python中生成器和迭代器的区别详解
2018/02/10 Python
Python数据分析pandas模块用法实例详解
2019/11/20 Python
Bravofly德国:预订廉价航班和酒店
2019/09/22 全球购物
单位承诺书格式
2014/05/21 职场文书
组织鉴定材料
2014/06/02 职场文书
全运会口号
2014/06/20 职场文书
科学发展观演讲稿
2014/09/11 职场文书
财务人员个人工作总结
2015/02/27 职场文书
幼儿教师师德师风自我评价
2015/03/05 职场文书
检讨书格式
2015/05/07 职场文书
专项资金申请报告
2015/05/15 职场文书
小学总务工作总结
2015/08/13 职场文书
MySQL 8.0 驱动与阿里druid版本兼容问题解决
2021/07/01 MySQL
python使用BeautifulSoup 解析HTML
2022/04/24 Python