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 相关文章推荐
tensorflow训练中出现nan问题的解决
Feb 10 Python
在CMD命令行中运行python脚本的方法
May 12 Python
Python高级用法总结
May 26 Python
Python OpenCV调用摄像头检测人脸并截图
Aug 20 Python
Python流程控制 while循环实现解析
Sep 02 Python
通过celery异步处理一个查询任务的完整代码
Nov 19 Python
Python CSV文件模块的使用案例分析
Dec 21 Python
使用Tensorboard工具查看Loss损失率
Feb 15 Python
python 使用raw socket进行TCP SYN扫描实例
May 05 Python
Python常用类型转换实现代码实例
Jul 28 Python
Python调用C/C++的方法解析
Aug 05 Python
python的链表基础知识点
Sep 13 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
xml+php动态载入与分页
2006/10/09 PHP
坏狼的PHP学习教程之第2天
2008/06/15 PHP
PHP 文章中的远程图片采集到本地的代码
2009/07/30 PHP
php 用checkbox一次性删除多条记录的方法
2010/02/23 PHP
PHP中date()日期函数有关参数整理
2011/07/19 PHP
php版小黄鸡simsimi聊天机器人接口分享
2014/01/26 PHP
window.parent调用父框架时 ie跟火狐不兼容问题
2009/07/30 Javascript
Javascript 中介者模式实例
2009/12/16 Javascript
juqery 学习之四 筛选过滤
2010/11/30 Javascript
jquery创建并行对象或者合并对象的实现代码
2012/10/10 Javascript
js操作table示例(个人心得)
2013/11/29 Javascript
php,js,css字符串截取的办法集锦
2014/09/26 Javascript
node.js(express)中使用Jcrop进行图片剪切上传功能
2017/04/21 Javascript
实现一个完整的Node.js RESTful API的示例
2017/09/29 Javascript
20个最常见的jQuery面试问题及答案
2018/05/23 jQuery
js实现多个倒计时并行 js拼团倒计时
2019/02/25 Javascript
详解Node.js使用token进行认证的简单示例
2020/05/25 Javascript
[01:11:48]Fnatic vs IG 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
[14:19]2018年度COSER大赛-完美盛典
2018/12/16 DOTA
Python实现线程状态监测简单示例
2018/03/28 Python
python运行时强制刷新缓冲区的方法
2019/01/14 Python
Python3实现取图片中特定的像素替换指定的颜色示例
2019/01/24 Python
python实现AES加密和解密
2019/03/27 Python
Pandas_cum累积计算和rolling滚动计算的用法详解
2019/07/04 Python
css3 iphone玻璃透明气泡完美实现
2013/03/20 HTML / CSS
结合CSS3的新特性来总结垂直居中的实现方法
2016/05/30 HTML / CSS
日本最大的眼镜购物网站:Oh My Glasses
2016/11/13 全球购物
2014年五一活动策划方案
2014/03/15 职场文书
建设投标担保书
2014/05/13 职场文书
校园文明标语
2014/06/13 职场文书
党支部群众路线整改措施思想汇报
2014/10/10 职场文书
2014年后勤管理工作总结
2014/12/01 职场文书
2016年“我们的节日·清明节”活动总结
2016/04/01 职场文书
PyQt5结合QtDesigner实现文本框读写操作
2021/06/11 Python
详解在SQLPlus中实现上下键翻查历史命令的功能
2022/03/18 SQL Server
Win11如何启用启动修复 ? Win11执行启动修复的三种方法
2022/04/08 数码科技