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继承问题
May 29 Python
浅谈python中的占位符
Nov 09 Python
Python实现将HTML转换成doc格式文件的方法示例
Nov 20 Python
用python实现的线程池实例代码
Jan 06 Python
Python框架Flask的基本数据库操作方法分析
Jul 13 Python
python操作小程序云数据库实现简单的增删改查功能
Jun 06 Python
PyQt5 对图片进行缩放的实例
Jun 18 Python
Python自动化导出zabbix数据并发邮件脚本
Aug 16 Python
Python 复平面绘图实例
Nov 21 Python
Python Matplotlib绘图基础知识代码解析
Aug 31 Python
属性与 @property 方法让你的python更高效
Sep 21 Python
去除python中的字符串空格的简单方法
Dec 22 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
在win7中搭建Linux+PHP 开发环境
2014/10/08 PHP
浅谈Laravel队列实现原理解决问题记录
2017/08/19 PHP
深入理解PHP中mt_rand()随机数的安全
2017/10/12 PHP
IE bug table元素的innerHTML
2010/01/11 Javascript
初试jQuery EasyUI 使用介绍
2010/04/01 Javascript
js multiple全选与取消全选实现代码
2012/12/04 Javascript
JavaScript起点(严格模式深度了解)
2013/01/28 Javascript
jquery实现通用的内容渐显Tab选项卡效果
2015/09/07 Javascript
jQuery使用$.ajax进行即时验证实例详解
2015/12/11 Javascript
Bootstrap对话框使用实例讲解
2016/09/24 Javascript
JavaScript 中调用 Kotlin 方法实例详解
2017/06/09 Javascript
使用veloticy-ui生成文字动画效果
2018/02/08 Javascript
vue 简单自动补全的输入框的示例
2018/03/12 Javascript
mpvue跳转页面及注意事项
2018/08/03 Javascript
Vue组件通信入门之Provide和Inject机制
2019/12/29 Javascript
vue跳转方式(打开新页面)及传参操作示例
2020/01/26 Javascript
javascript设计模式 ? 迭代器模式原理与用法实例分析
2020/04/17 Javascript
vue+openlayers绘制省市边界线
2020/12/24 Vue.js
Python的ORM框架SQLObject入门实例
2014/04/28 Python
python的tkinter布局之简单的聊天窗口实现方法
2014/09/03 Python
Python实现简单登录验证
2016/04/13 Python
virtualenv实现多个版本Python共存
2017/08/21 Python
PyQt5每天必学之带有标签的复选框
2018/04/19 Python
利用numpy和pandas处理csv文件中的时间方法
2018/04/19 Python
Python自动化导出zabbix数据并发邮件脚本
2019/08/16 Python
CSS3盒子模型详解
2013/04/24 HTML / CSS
Adobe Html5 Extension开发初体验图文教程
2017/11/14 HTML / CSS
iframe与window.onload如何使用详解
2020/05/07 HTML / CSS
SK-II神仙水美国官网:SK-II美国
2020/02/25 全球购物
Python面试题:Python里面如何生成随机数
2015/03/12 面试题
消防安全检查制度
2014/02/04 职场文书
企业员工培训感言
2014/02/26 职场文书
群众路线教育实践活动心得体会(四风)
2014/11/03 职场文书
2016大学生毕业实习心得体会
2016/01/23 职场文书
Java SSH 秘钥连接mysql数据库的方法
2021/06/28 Java/Android
Qt自定义Plot实现曲线绘制的详细过程
2021/11/02 Python