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线程中对join方法的运用的教程
Apr 09 Python
python解决pandas处理缺失值为空字符串的问题
Apr 08 Python
Python中判断输入是否为数字的实现代码
May 26 Python
python networkx 包绘制复杂网络关系图的实现
Jul 10 Python
Python爬虫 bilibili视频弹幕提取过程详解
Jul 31 Python
pytorch 可视化feature map的示例代码
Aug 20 Python
使用python远程操作linux过程解析
Dec 04 Python
使用python动态生成波形曲线的实现
Dec 04 Python
tensorflow:指定gpu 限制使用量百分比,设置最小使用量的实现
Feb 06 Python
python爬虫请求头设置代码
Jul 28 Python
python在一个范围内取随机数的简单实例
Aug 16 Python
详解Python之Scrapy爬虫教程NBA球员数据存放到Mysql数据库
Jan 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获取网站域名和地址的代码
2008/08/17 PHP
php中将数组存到文件里的实现代码
2012/01/19 PHP
理解PHP中的stdClass类
2014/04/18 PHP
PHP调用Linux命令权限不足问题解决方法
2015/02/07 PHP
PHP判断JSON对象是否存在的方法(推荐)
2016/07/06 PHP
详谈PHP中的密码安全性Password Hashing
2017/02/04 PHP
yii2 url重写并隐藏index.php方法
2018/12/10 PHP
又一个小巧的图片预加载类
2007/05/05 Javascript
一个刚完成的layout(拖动流畅,不受iframe影响)
2007/08/17 Javascript
JQuery打造PHP的AJAX表单提交实例
2009/11/03 Javascript
Extjs学习笔记之九 数据模型(上)
2010/01/11 Javascript
仿当当网淘宝网等主流电子商务网站商品分类导航菜单
2013/09/25 Javascript
js带前后翻页的图片切换效果代码分享
2015/09/08 Javascript
jQuery的选择器中的通配符[id^='code']或[name^='code']及jquery选择器总结
2015/12/24 Javascript
AngularJS常见过滤器用法实例总结
2017/07/06 Javascript
使用layui定义一个模块并使用的例子
2019/09/14 Javascript
微信小程序停止其他视频播放当前视频的实例代码
2019/12/25 Javascript
Vue 中使用lodash对事件进行防抖和节流操作
2020/07/26 Javascript
Python的Flask框架中web表单的教程
2015/04/20 Python
使用XML库的方式,实现RPC通信的方法(推荐)
2017/06/14 Python
详解Python中字符串前“b”,“r”,“u”,“f”的作用
2019/12/18 Python
将 Ubuntu 16 和 18 上的 python 升级到最新 python3.8 的方法教程
2020/03/11 Python
解决tensorflow 释放图,删除变量问题
2020/06/23 Python
Answear匈牙利:来自全球200多个知名时尚品牌
2017/04/21 全球购物
美国网上鞋子零售商:Dr. Scholl’s Shoes
2017/11/17 全球购物
日本著名化妆品零售网站:Cosme Land
2019/03/01 全球购物
预订旅游活动、景点和旅游:GetYourGuide
2019/09/29 全球购物
安卓程序员求职信
2014/02/28 职场文书
销售求职信范文
2014/05/26 职场文书
大学学雷锋活动总结
2014/06/26 职场文书
个人事迹材料范文
2014/12/29 职场文书
西柏坡导游词
2015/02/05 职场文书
志愿者个人总结
2015/03/03 职场文书
警告通知
2015/04/25 职场文书
防溺水安全教育主题班会
2015/08/12 职场文书
python3+PyQt5+Qt Designer实现界面可视化
2021/06/10 Python