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 20 Python
举例讲解Python中的list列表数据结构用法
Mar 12 Python
在Python 2.7即将停止支持时,我们为你带来了一份python 3.x迁移指南
Jan 30 Python
Python编程argparse入门浅析
Feb 07 Python
使用python爬取B站千万级数据
Jun 08 Python
python实现知乎高颜值图片爬取
Aug 12 Python
Django之编辑时根据条件跳转回原页面的方法
Aug 21 Python
Python socket连接中的粘包、精确传输问题实例分析
Mar 24 Python
Python decorator拦截器代码实例解析
Apr 04 Python
python异常处理之try finally不报错的原因
May 18 Python
通过Python扫描代码关键字并进行预警的实现方法
May 24 Python
Python面向对象之内置函数相关知识总结
Jun 24 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将对象转换成数组的方法(兼容多维数组类型)
2013/06/21 PHP
PHP魔术方法的使用示例
2015/06/23 PHP
CI分页类首页、尾页不显示的解决方法
2016/03/28 PHP
php 二维数组时间排序实现代码
2016/11/19 PHP
laravel 解决Eloquent ORM的save方法无法插入数据的问题
2019/10/21 PHP
数组方法解决JS字符串连接性能问题有争议
2011/01/12 Javascript
setTimeout和setInterval的区别你真的了解吗?
2011/03/31 Javascript
基于jquery实现拆分姓名的方法(纯JS版)
2013/05/08 Javascript
jQuery中focus事件用法实例
2014/12/26 Javascript
Bootstrap table的使用方法
2016/11/02 Javascript
详解Vue.js动态绑定class
2016/12/20 Javascript
js使用highlight.js高亮你的代码
2017/08/18 Javascript
React 无状态组件(Stateless Component) 与高阶组件
2018/08/14 Javascript
浅谈webpack SplitChunksPlugin实用指南
2018/09/17 Javascript
分享JS表单验证源码(带错误提示及密码等级)
2020/01/05 Javascript
jQuery实现计算器功能
2020/10/19 jQuery
[32:26]EG vs IG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python标准库defaultdict模块使用示例
2015/04/28 Python
Python创建模块及模块导入的方法
2015/05/27 Python
Python 基础教程之闭包的使用方法
2017/09/29 Python
Python进阶之尾递归的用法实例
2018/01/31 Python
python对绑定事件的鼠标、按键的判断实例
2019/07/17 Python
Python存储读取HDF5文件代码解析
2020/11/25 Python
size?法国官网:英国伦敦的球鞋精品店
2020/03/15 全球购物
大学生旅游业创业计划书
2014/01/29 职场文书
大学学习个人的自我评价
2014/02/18 职场文书
品质管理部岗位职责范文
2014/03/01 职场文书
给孩子的新年寄语
2014/04/08 职场文书
文案策划专业自荐信
2014/07/07 职场文书
2015大学生暑期实习报告
2015/07/13 职场文书
记者节感言
2015/08/03 职场文书
班主任培训研修日志
2015/11/13 职场文书
2016年秋季趣味运动会开幕词
2016/03/04 职场文书
mybatis 获取无数据的字段不显示的问题
2021/07/15 Java/Android
MySQL RC事务隔离的实现
2022/03/31 MySQL
Mysql中的触发器定义及语法介绍
2022/06/25 MySQL