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中encode()方法的使用简介
May 18 Python
python清除指定目录内所有文件中script的方法
Jun 30 Python
Python三级菜单的实例
Sep 13 Python
深入理解Django的自定义过滤器
Oct 17 Python
python实现决策树分类算法
Dec 21 Python
利用Python如何实现一个小说网站雏形
Nov 23 Python
使用Python测试Ping主机IP和某端口是否开放的实例
Dec 17 Python
详解python破解zip文件密码的方法
Jan 13 Python
详解python tcp编程
Aug 24 Python
Python列表元素删除和remove()方法详解
Jan 04 Python
Pycharm制作搞怪弹窗的实现代码
Feb 19 Python
LyScript实现绕过反调试保护的示例详解
Aug 14 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实现从上传文件创建缩略图的方法
2015/04/02 PHP
学习ExtJS fit布局使用说明
2009/10/08 Javascript
JQuery 绑定事件时传递参数的实现方法
2009/10/13 Javascript
aspx中利用js实现确认删除代码
2010/07/22 Javascript
Javascript面向对象之四 继承
2011/02/08 Javascript
原生JS操作网页给p元素添加onclick事件及表格隔行变色
2013/12/01 Javascript
jquery操作select详解(取值,设置选中)
2014/02/07 Javascript
js函数模拟显示桌面.scf程序示例
2014/04/20 Javascript
setInterval计时器不准的问题解决方法
2014/05/08 Javascript
js获取窗口相对于屏幕左边和上边的位置坐标
2014/05/15 Javascript
Ajax局部更新导致JS事件重复触发问题的解决方法
2014/10/14 Javascript
JS实现重新加载当前页面或者父页面的几种方法
2016/11/30 Javascript
从零开始学习Node.js系列教程四:多页面实现的数学运算示例
2017/04/13 Javascript
JS实现去除数组中重复json的方法示例
2017/12/21 Javascript
Nodejs下使用gm圆形裁剪并合成图片的示例
2018/02/22 NodeJs
基于Nodejs的Tcp封包和解包的理解
2018/09/19 NodeJs
记一次用vue做的活动页的方法步骤
2019/04/11 Javascript
使用JS判断页面是首次被加载还是刷新
2019/05/26 Javascript
关于微信小程序map组件z-index的层级问题分析
2019/07/09 Javascript
vue用elementui写form表单时,在label里添加空格操作
2020/08/13 Javascript
JavaScript 防盗链的原理以及破解方法
2020/12/29 Javascript
跟老齐学Python之大话题小函数(2)
2014/10/10 Python
tensorflow TFRecords文件的生成和读取的方法
2018/02/06 Python
Python常用模块之requests模块用法分析
2019/05/15 Python
TensorFlow2.1.0最新版本安装详细教程
2020/04/08 Python
python如何实现递归转非递归
2021/02/25 Python
用HTML5.0制作网页的教程
2010/05/30 HTML / CSS
意大利领先的线上奢侈品销售电商:Eleonora Bonucci
2017/10/17 全球购物
Book Depository欧盟:一家领先的国际图书零售商
2019/05/21 全球购物
致1500米运动员广播稿
2014/02/07 职场文书
幼儿园春季开学寄语
2014/04/03 职场文书
政风行风建设整改方案
2014/10/27 职场文书
人工作失职检讨书
2015/05/05 职场文书
普希金的诗歌赏析(3首)
2019/08/20 职场文书
SQL Server——索引+基于单表的数据插入与简单查询【1】
2021/04/05 SQL Server
船舶调度指挥系统——助力智慧海事
2022/02/18 无线电