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根据出生日期返回年龄的方法
Mar 26 Python
Python编程中字符串和列表的基本知识讲解
Oct 14 Python
Python中list初始化方法示例
Sep 18 Python
python如何统计序列中元素
Jul 31 Python
django的登录注册系统的示例代码
May 14 Python
python list格式数据excel导出方法
Oct 31 Python
对python打乱数据集中X,y标签对的方法详解
Dec 14 Python
PyQt5实现从主窗口打开子窗口的方法
Jun 19 Python
python全栈要学什么 python全栈学习路线
Jun 28 Python
python正则-re的用法详解
Jul 28 Python
python3中rank函数的用法
Nov 27 Python
Pygame Time时间控制的具体使用详解
Nov 17 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实现MVC开发得最简单的方法――模型
2007/04/10 PHP
php实现mysql同步的实现方法
2009/10/21 PHP
第二章 PHP入门基础之php代码写法
2011/12/30 PHP
js客户端快捷键管理类的较完整实现和应用
2010/06/08 Javascript
jquery 滚动条事件简单实例
2013/07/12 Javascript
javascript实现简单的进度条
2015/07/02 Javascript
AJAX实现瀑布流触发分页与分页触发瀑布流的方法
2016/05/23 Javascript
原生js实现jquery函数animate()动画效果的简单实例
2016/08/21 Javascript
Javascript实现从小到大的数组转换成二叉搜索树
2017/06/13 Javascript
实例分析js事件循环机制
2017/12/13 Javascript
使用express+multer实现node中的图片上传功能
2018/02/02 Javascript
Vue 中mixin 的用法详解
2018/04/23 Javascript
vux uploader 图片上传组件的安装使用方法
2018/05/15 Javascript
Layui给数据表格动态添加一行并跳转到添加行所在页的方法
2018/08/20 Javascript
Nuxt.js之自动路由原理的实现方法
2018/11/21 Javascript
vue项目打包后怎样优雅的解决跨域
2019/05/26 Javascript
node.js使用yargs处理命令行参数操作示例
2020/02/11 Javascript
python处理大数字的方法
2015/05/27 Python
python计算圆周率pi的方法
2015/07/11 Python
在Django中管理Users和Permissions以及Groups的方法
2015/07/23 Python
详解使用 pyenv 管理多个版本 python 环境
2017/10/19 Python
python生成密码字典的方法
2018/07/06 Python
python多进程下实现日志记录按时间分割
2019/07/22 Python
tensorflow查看ckpt各节点名称实例
2020/01/21 Python
Django 解决上传文件时,request.FILES为空的问题
2020/05/20 Python
PyTorch安装与基本使用详解
2020/08/31 Python
在Python中字典按值排序的实现方法
2020/11/12 Python
Scholastic父母商店:儿童书籍
2017/01/01 全球购物
String s = new String(“xyz”);创建了几个String Object?
2015/08/05 面试题
《日月潭》教学反思
2014/02/28 职场文书
房产买卖委托公证书
2014/04/04 职场文书
临床护理求职信
2014/04/26 职场文书
党员对照检查剖析材料
2014/10/13 职场文书
2014业务员年终工作总结
2014/12/09 职场文书
2015年客房服务员工作总结
2015/05/15 职场文书
python基础之文件操作
2021/10/24 Python