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中关于时间和日期函数的常用计算总结(time和datatime)
Mar 08 Python
Python使用Scrapy爬虫框架全站爬取图片并保存本地的实现代码
Mar 04 Python
python数字图像处理之高级形态学处理
Apr 27 Python
python multiprocessing多进程变量共享与加锁的实现
Oct 02 Python
基于python求两个列表的并集.交集.差集
Feb 10 Python
python词云库wordCloud使用方法详解(解决中文乱码)
Feb 17 Python
Django操作session 的方法
Mar 09 Python
如何使用scrapy中的ItemLoader提取数据
Sep 30 Python
Python调用高德API实现批量地址转经纬度并写入表格的功能
Jan 12 Python
完美解决torch.cuda.is_available()一直返回False的玄学方法
Feb 06 Python
Matplotlib绘制混淆矩阵的实现
May 27 Python
python调用ffmpeg命令行工具便捷操作视频示例实现过程
Nov 01 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
PHP4与PHP5的时间格式问题
2008/02/17 PHP
ie6 动态缩略图不显示的原因
2009/06/21 PHP
php实现读取超大文件的方法
2014/07/28 PHP
php获取本周星期一具体日期的方法
2015/04/20 PHP
php中smarty区域循环的方法
2015/06/11 PHP
php实现和c#一致的DES加密解密实例
2017/07/24 PHP
基于Jquery的温度计动画效果
2010/06/18 Javascript
jquery实现textarea输入字符控制(仿微博输入控制字符)
2013/04/26 Javascript
ie7+背景透明文字不透明超级简单的实现方法
2014/01/17 Javascript
教你如何使用node.js制作代理服务器
2014/11/26 Javascript
javascript特殊日历控件分享
2016/03/07 Javascript
深入理解JS中的Function.prototype.bind()方法
2016/10/11 Javascript
JavaScript评论点赞功能的实现方法
2017/03/13 Javascript
vue 通过下拉框组件学习vue中的父子通讯
2017/12/19 Javascript
Angular数据绑定机制原理
2018/04/17 Javascript
用JavaScript实现贪吃蛇游戏
2020/10/23 Javascript
Python实现约瑟夫环问题的方法
2016/05/03 Python
Python向Excel中插入图片的简单实现方法
2018/04/24 Python
python编写简易聊天室实现局域网内聊天功能
2018/07/28 Python
详解Django的model查询操作与查询性能优化
2018/10/16 Python
python实发邮件实例详解
2019/11/11 Python
详解Python中的format格式化函数的使用方法
2019/11/20 Python
Python操作MySQL数据库实例详解【安装、连接、增删改查等】
2020/01/17 Python
Python常用数据分析模块原理解析
2020/07/20 Python
Python中使用aiohttp模拟服务器出现错误问题及解决方法
2020/10/31 Python
css3 仿写阿里云水纹效果的示例代码
2018/02/10 HTML / CSS
HTML5给汉字加拼音收起展开组件的实现代码
2020/04/08 HTML / CSS
Under Armour澳大利亚官网:美国知名的高端功能性运动品牌
2018/02/22 全球购物
实习生自我鉴定范文
2013/12/05 职场文书
九年级科学教学反思
2014/01/29 职场文书
《盲人摸象》教学反思
2014/02/16 职场文书
北京奥运会主题口号
2014/06/13 职场文书
农村党支部书记党群众路线四风问题整改措施
2014/09/26 职场文书
交警作风整顿剖析材料
2014/10/11 职场文书
MATLAB 如何求取离散点的曲率最大值
2021/04/16 Python
div与span之间的区别与使用介绍
2021/12/06 HTML / CSS