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的几条建议分享
Feb 10 Python
解决python2.7 查询mysql时出现中文乱码
Oct 09 Python
浅谈Python 的枚举 Enum
Jun 12 Python
转换科学计数法的数值字符串为decimal类型的方法
Jul 16 Python
python实现京东秒杀功能
Jul 30 Python
Python编程深度学习绘图库之matplotlib
Dec 28 Python
Python找出列表中出现次数最多的元素三种方式
Feb 24 Python
python3爬虫中异步协程的用法
Jul 10 Python
python使用建议与技巧分享(二)
Aug 17 Python
浅谈Selenium+Webdriver 常用的元素定位方式
Jan 13 Python
关于Python中*args和**kwargs的深入理解
Aug 07 Python
关于pytest结合csv模块实现csv格式的数据驱动问题
May 30 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实现MySQL更新记录的代码
2008/06/07 PHP
js静态作用域的功能。
2006/12/25 Javascript
用javascript实现的图片马赛克后显示并切换加文字功能
2007/04/21 Javascript
用JavaScript调用WebService的示例
2008/04/07 Javascript
通过jQuery打造支持汉字,拼音,英文快速定位查询的超级select插件
2010/06/18 Javascript
jquery中:input和input的区别分析
2011/07/13 Javascript
Raphael一个用于在网页中绘制矢量图形的Javascript库
2013/01/08 Javascript
jquery移除、绑定、触发元素事件使用示例详解
2014/04/10 Javascript
浅谈JavaScript中的字符编码转换问题
2015/07/07 Javascript
javascript实现查找数组中最大值方法汇总
2016/02/13 Javascript
js简单获取表单中单选按钮值的方法
2016/08/23 Javascript
使用Vue.js创建一个时间跟踪的单页应用
2016/11/28 Javascript
html5 canvas 详细使用教程
2017/01/20 Javascript
AngularJS实用基础知识_入门必备篇(推荐)
2017/07/10 Javascript
浅谈Fetch 数据交互方式
2018/12/20 Javascript
Vue核心概念Action的总结
2019/01/18 Javascript
Node.js学习教程之Module模块
2019/09/03 Javascript
jQuery中getJSON跨域原理的深入讲解
2020/09/02 jQuery
python实现将html表格转换成CSV文件的方法
2015/06/28 Python
详解python时间模块中的datetime模块
2016/01/13 Python
Google开源的Python格式化工具YAPF的安装和使用教程
2016/05/31 Python
python win32 简单操作方法
2017/05/25 Python
Python实现动态添加属性和方法操作示例
2018/07/25 Python
appium+python adb常用命令分享
2020/03/06 Python
Pyspark读取parquet数据过程解析
2020/03/27 Python
在jupyter notebook中调用.ipynb文件方式
2020/04/14 Python
Pytorch之Tensor和Numpy之间的转换的实现方法
2020/09/03 Python
浅谈anaconda python 版本对应关系
2020/10/07 Python
Python reversed反转序列并生成可迭代对象
2020/10/22 Python
初中生三年学习生活的自我评价
2013/11/03 职场文书
陈欧的广告词
2014/03/18 职场文书
厂区绿化方案
2014/05/08 职场文书
英文商务邀请函范文
2015/01/31 职场文书
2016年4月份红领巾广播稿
2015/12/21 职场文书
Python爬虫:从m3u8文件里提取小视频的正确操作
2021/05/14 Python
Nginx如何限制IP访问只允许特定域名访问
2022/07/23 Servers