Python进阶之尾递归的用法实例


Posted in Python onJanuary 31, 2018

作者是一名沉迷于Python无法自拔的蛇友,为提高水平,把Python的重点和有趣的实例发在简书上。

尾递归

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

(来源于不说人话的某度)

下面是笔者的个人理解:把计算出的值存在函数内部(当然不止尾递归)是其计算方法,从而不用在栈中去创建一个新的,这样就大大节省了空间。函数调用中最后返回的结果是单纯的递归函数调用(或返回结果)就是尾递归。

实例

实例还是和笔者的上一篇文章相同,建议读者阅读 Python —— 递归

1、阶乘

常规递归阶乘:

def factorial(n): 
  if n == 0:
    return 1
  return factorial(n - 1) * n

我们来看一下执行过程:

factorial(4) 
factorial(3) * 4 
factorial(2) * 3 * 4 
factorial(1) * 2 * 3 * 4 
factorial(0) * 1 * 2 * 3 * 4 
1 * 1 * 2 * 3 * 4 
1 * 2 * 3 * 4 
2 * 3 * 4 
6 * 4 
24

但是如果把上面的函数写成如下形式:

def factorial(n, acc=1): 
  if n == 0:
    return acc
  return factorial(n - 1, n * acc)

我们再看下执行过程:

factorial(4, 1) 
factorial(3, 4) 
factorial(2, 12) 
factorial(1, 24) 
factorial(0, 24) 
24

很直观的就可以看出,这次的 factorial 函数在递归调用的时候不会产生一系列逐渐增多的中间变量了,而是将状态保存在 acc 这个变量中。而这种形式的递归,就叫做尾递归。

2、斐波那契数列

常规递斐波那契数列:

def fib(n):
  if n < 2:
    return n
  else:
    return fib(n - 1) + fib(n - 2)

而尾递归:

def fib_tail(n, r, t):
  if n == 1:
    return r
  else:
    return fib_tail(n - 1, t, r + t)

一下子就充满了逼格,还高效了许多,何乐而不为呢!

总结

可以看出,在每次递归调用的时候,都会产生一个临时变量,导致进程内存占用量增大一些。这样执行一些递归层数比较深的代码时,除了无谓的内存浪费,还有可能导致著名的堆栈溢出错误。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python缩进区别分析
Feb 15 Python
Python列表append和+的区别浅析
Feb 02 Python
Python利用正则表达式匹配并截取指定子串及去重的方法
Jul 30 Python
使用Python的urllib和urllib2模块制作爬虫的实例教程
Jan 20 Python
Python爬虫:通过关键字爬取百度图片
Feb 17 Python
python监控键盘输入实例代码
Feb 09 Python
python 巧用正则寻找字符串中的特定字符的位置方法
May 02 Python
对python for 文件指定行读写操作详解
Dec 29 Python
PyQt打开保存对话框的方法和使用详解
Feb 27 Python
详解Python爬取并下载《电影天堂》3千多部电影
Apr 26 Python
Python内置异常类型全面汇总
May 28 Python
Python基于pandas绘制散点图矩阵代码实例
Jun 04 Python
简单的python协同过滤程序实例代码
Jan 31 #Python
Python进阶之递归函数的用法及其示例
Jan 31 #Python
Python tkinter事件高级用法实例
Jan 31 #Python
pyqt5自定义信号实例解析
Jan 31 #Python
Python使用flask框架操作sqlite3的两种方式
Jan 31 #Python
pyqt5简介及安装方法介绍
Jan 31 #Python
Python实现的圆形绘制(画圆)示例
Jan 31 #Python
You might like
php为字符串前后添加指定数量字符的方法
2015/05/04 PHP
PHP给前端返回一个JSON对象的实例讲解
2018/05/31 PHP
基于jquery的滚动新闻列表
2010/06/19 Javascript
jquery cookie的用法总结
2013/11/18 Javascript
window.open()详解及浏览器兼容性问题示例探讨
2014/05/29 Javascript
json属性名为什么要双引号(个人猜测)
2014/07/31 Javascript
JavaScript极简入门教程(三):数组
2014/10/25 Javascript
jQuery中:last-child选择器用法实例
2014/12/31 Javascript
Linux下编译安装php libevent扩展实例
2015/02/14 Javascript
分类解析jQuery选择器
2016/11/23 Javascript
JavaScript DOM节点操作实例小结(新建,删除HTML元素)
2017/01/19 Javascript
js的OOP继承实现(必看篇)
2017/02/18 Javascript
vue中七牛插件使用的实例代码
2017/07/28 Javascript
JavaScript笛卡尔积超简单实现算法示例
2018/07/30 Javascript
vue中过滤器filter的讲解
2019/01/21 Javascript
微信小程序学习笔记之跳转页面、传递参数获得数据操作图文详解
2019/03/28 Javascript
vue项目中全局引入1个.scss文件的问题解决
2019/08/01 Javascript
vue的注意规范之v-if 与 v-for 一起使用教程
2019/08/04 Javascript
浅谈vue中$bus的使用和涉及到的问题
2020/07/28 Javascript
微信小程序实现单个或多个倒计时功能
2020/11/01 Javascript
tornado框架blog模块分析与使用
2013/11/21 Python
在windows下快速搭建web.py开发框架方法
2016/04/22 Python
浅谈pandas中shift和diff函数关系
2018/04/08 Python
python2.7实现爬虫网页数据
2018/05/25 Python
python GUI框架pyqt5 对图片进行流式布局的方法(瀑布流flowlayout)
2020/03/12 Python
在pycharm中使用pipenv创建虚拟环境和安装django的详细教程
2020/11/30 Python
浅析HTML5 Landmark
2020/09/11 HTML / CSS
碧欧泉法国官网:Biotherm法国
2019/10/23 全球购物
综合办公室个人的自我评价
2013/12/22 职场文书
发展部经理职责规定
2014/02/22 职场文书
学生鉴定评语大全
2014/05/05 职场文书
教师考核鉴定意见
2015/06/05 职场文书
国庆节主题班会
2015/08/15 职场文书
发工资啦!教你用Python实现邮箱自动群发工资条
2021/05/10 Python
java多态注意项小结
2021/10/16 Java/Android
JavaScript严格模式不支持八进制的问题讲解
2021/11/07 Javascript