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 14 Python
Python3使用requests发闪存的方法
May 11 Python
Python脚本实现Web漏洞扫描工具
Oct 25 Python
python之django母板页面的使用
Jul 03 Python
python 将字符串完成特定的向右移动方法
Jun 11 Python
pandas 数据索引与选取的实现方法
Jun 21 Python
python中对数据进行各种排序的方法
Jul 02 Python
python实现复制文件到指定目录
Oct 16 Python
python错误调试及单元文档测试过程解析
Dec 19 Python
通过Python实现一个简单的html页面
May 16 Python
使用Keras实现简单线性回归模型操作
Jun 12 Python
python绘图pyecharts+pandas的使用详解
Dec 13 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
解析linux下安装memcacheq(mcq)全过程笔记
2013/06/27 PHP
php中文字符串截取方法实例总结
2014/09/30 PHP
php ImageMagick windows下安装教程
2015/01/26 PHP
php对象在内存中的存在形式分析
2015/02/03 PHP
thinkphp5 模型实例化获得数据对象的教程
2019/10/18 PHP
PhpStorm 如何优雅的调试Hyperf的方法步骤
2019/11/24 PHP
浅析Javascript使用include/require
2013/11/13 Javascript
js 获取、清空input type=&quot;file&quot;的值(示例代码)
2013/12/24 Javascript
理解javascript闭包
2015/12/15 Javascript
深入浅析AngularJS中的module(模块)
2016/01/04 Javascript
理解JS事件循环
2016/01/07 Javascript
axios基本入门用法教程
2017/03/25 Javascript
基于ionic实现下拉刷新功能
2018/05/10 Javascript
微信小程序公用参数与公用方法用法示例
2019/01/09 Javascript
[02:16]卖萌的僵尸 DOTA2神话信使飞僵小宝来袭
2014/03/24 DOTA
浅谈Python 中整型对象的存储问题
2016/05/16 Python
Python 操作MySQL详解及实例
2017/04/30 Python
Python变量赋值的秘密分享
2018/04/03 Python
python绘制立方体的方法
2018/07/02 Python
python 随机打乱 图片和对应的标签方法
2018/12/14 Python
python算法题 链表反转详解
2019/07/02 Python
Python Pandas 箱线图的实现
2019/07/23 Python
django框架创建应用操作示例
2019/09/26 Python
Python3常见函数range()用法详解
2019/12/30 Python
python argparse模块通过后台传递参数实例
2020/04/20 Python
Python类class参数self原理解析
2020/11/19 Python
Debenhams爱尔兰:英国知名的百货公司
2017/01/02 全球购物
灵泰克Java笔试题
2016/01/09 面试题
中药专业大学生医药工作求职信
2013/10/25 职场文书
动员大会主持词
2014/03/20 职场文书
竞选体育委员演讲稿
2014/04/26 职场文书
关于雷锋的演讲稿
2014/05/10 职场文书
危货运输企业安全生产责任书
2014/07/28 职场文书
龙门石窟导游词
2015/02/02 职场文书
承兑汇票延期证明
2015/06/23 职场文书
Python爬虫之爬取哔哩哔哩热门视频排行榜
2021/04/28 Python