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判断一个集合是否包含了另外一个集合中所有项的方法
Jun 30 Python
Python实现简单遗传算法(SGA)
Jan 29 Python
解决tensorflow测试模型时NotFoundError错误的问题
Jul 27 Python
Django框架使用mysql视图操作示例
May 15 Python
图文详解python安装Scrapy框架步骤
May 20 Python
Python绘制频率分布直方图的示例
Jul 08 Python
python线程的几种创建方式详解
Aug 29 Python
使用turtle绘制五角星、分形树
Oct 06 Python
基于Python中的yield表达式介绍
Nov 19 Python
Python使用type动态创建类操作示例
Feb 29 Python
利用Python的folium包绘制城市道路图的实现示例
Aug 24 Python
详解python tkinter 图片插入问题
Sep 03 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
浅谈ThinkPHP的URL重写
2014/11/25 PHP
php强制下载文件函数
2016/08/24 PHP
PHP基于timestamp和nonce实现的防止重放攻击方案分析
2019/07/26 PHP
根据鼠标的位置动态的控制层的位置
2009/11/24 Javascript
JavaScript浏览器选项卡效果
2010/08/25 Javascript
从零开始学习jQuery (十一) 实战表单验证与自动完成提示插件
2011/02/23 Javascript
jQuery的one()方法用法实例
2015/01/19 Javascript
JS往数组中添加项性能分析
2015/02/25 Javascript
深入学习JavaScript中的Rest参数和参数默认值
2015/07/28 Javascript
JS实现新浪博客左侧的Blog管理菜单效果代码
2015/10/22 Javascript
jQuery实现获取绑定自定义事件元素的方法
2015/12/02 Javascript
JavaScript动态生成二维码图片
2016/04/20 Javascript
JS功能代码集锦
2016/05/04 Javascript
js手机号批量滚动抽奖实现代码
2020/04/17 Javascript
JavaScript实现类似淘宝的购物车效果
2017/03/16 Javascript
angularjs定时任务的设置与清除示例
2017/06/02 Javascript
js实现每日签到功能
2018/11/29 Javascript
react 生命周期实例分析
2020/05/18 Javascript
[52:31]VP vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
讲解Python的Scrapy爬虫框架使用代理进行采集的方法
2016/02/18 Python
Python使用win32com模块实现数据库表结构自动生成word表格的方法
2018/07/17 Python
Windows下安装Scrapy
2018/10/17 Python
python 运用Django 开发后台接口的实例
2018/12/11 Python
python Selenium实现付费音乐批量下载的实现方法
2019/01/24 Python
python画图的函数用法以及技巧
2019/06/28 Python
python3实现高效的端口扫描
2019/08/31 Python
浅析HTML5中的download属性使用
2019/03/13 HTML / CSS
酒店应聘自荐信
2013/11/09 职场文书
运动会通讯稿500字
2014/02/20 职场文书
个人充满哲理的自我评价
2014/02/20 职场文书
学习演讲稿范文
2014/05/10 职场文书
求职自我推荐信
2014/06/25 职场文书
员工试用期自我鉴定范文
2014/09/15 职场文书
学校2014重阳节活动策划方案
2014/09/16 职场文书
荆州古城导游词
2015/02/06 职场文书
源码安装apache脚本部署过程详解
2022/09/23 Servers