在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

举个例子,我们来计算阶乘n! = 1 * 2 * 3 * ... * n,用函数fact(n)表示,可以看出:

fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n

所以,fact(n)可以表示为n * fact(n-1),只有n=1时需要特殊处理。

于是,fact(n)用递归的方式写出来就是:

def fact(n):

if n == 1:

return 1

return n * fact(n - 1)

print(fact(5))

递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。

使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就

会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。可以

试试fact(1000):

它会报该错误:RecursionError: maximum recursion depth exceeded in comparison

解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。

尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。

注意:不是所有语言都有尾递归优化的(Java就没有)

def f(n):

return fact_iter(n, 1) # 返回的是另一个递归调用函数的结果

def fact_iter(num, product): # num是想要计算的值,product是结果

if num == 1:

return product

return fact_iter(num - 1, num * product) # 将乘积结果传入函数

可以看到尾递归的函数比原始的版本多了1个参数,一个起到收集器(accumulator)的作用,记录每上一次栈的返回值,因为原来栈的空间会被下一层递归覆盖。

尾递归调用时,如果做了优化,栈不会增长,因此,无论多少次调用也不会导致栈溢出。

遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的fact(n)函数改成尾递归方式,也会导致栈溢出。

小结

使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。

针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环。

Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。

python递归函数特点_python中对递归函数的理解相关推荐

  1. python中递归函数写法_python中递归函数如何创建

    递归函数是编程技术之一,这意味着你的程序包含你自己调用的函数.与迭代函数一样,在多次执行类似处理时可以使用递归函数,但递归函数可以通过用简单的代码替换它们来处理更复杂的问题.本篇文章我们就来看看pyt ...

  2. python递归函数定义_python中递归函数

    python之递归函数 一.递归函数定义 什么是递归: 在一个函数里在调用这个函数本身 最大递归层数是:997 最大递归层数可以修改,建议不要去修改 (如果997层数递归都没解决你的问题那只有两个原因 ...

  3. python中的递归函数是什么_Python中的递归函数

    递归函数recursion 函数直接或者间接调用自身,这就是递归函数.能用递归函数解决的问题,一般使用循环也可以解决.递归函数一定要有边界 递归函数的案例 一.斐波那契数列 求斐波那契数列前n项 de ...

  4. python map用法_Python中ChainMap的一种实用用法

    Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发. 简而言之ChainMap:将多个字典视为一个,解锁Python超能力. Python标准库中的集合模块包含 ...

  5. python基本统计量_Python中简单统计量的计算

    本篇文章给大家带来的内容是关于Python中简单统计量的计算,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 1.这些操作都要确保已经在电脑中安装好了Anaconda集成库,如果安装好 ...

  6. python 浮点数比较_Python中的浮点数

    浮点数在计算机中表达为二进制(binary)小数.例如:十进制小数: 0.125 是 1/10 + 2/100 + 5/1000 的值. 类似地,二进制小数: 0.001 是 0/2 + 0/4 + ...

  7. python解析原理_Python 中 -m 的典型用法、原理解析与发展演变

    在命令行中使用 Python 时,它可以接收大约 20 个选项(option),语法格式如下: python [-bBdEhiIOqsSuvVWx?] [-c command | -m module- ...

  8. lambda python什么意思_python中lambda是指什么

    在学习python的过程中,lambda的语法时常会使人感到困惑,lambda是什么,为什么要使用lambda,是不是必须使用lambda? 下面就上面的问题进行一下解答. lambda是什么? 看个 ...

  9. python正则表达式空格_python中的正则表达式的使用

    一.正则表达式简介 正则表达式:又称正规表示式.正规表示法.正规表达式.规则表示式.常规表示法(英语:Regular Expression,在代码中常简写为regex.regexp或者是RE),是计算 ...

最新文章

  1. 手机经常提示找不到服务器,经常出现找不到服务器是什么原因?什么网也打 – 手机爱问...
  2. 设置apache目录认证
  3. Cocoapods ----- pod install报错
  4. webpack4.0 babel配置遇到的问题
  5. CDP客户数据管理平台体系化搭建
  6. Java 之 String 类型
  7. 《天天数学》连载14:一月十四日
  8. 很多人在网络上创业看不到本质
  9. CISCO的NAT配置笔记
  10. 浅谈浏览器端JavaScript跨域解决方法
  11. Git Push,Pull,Clone出现SSL certificate problem: unable to get local issuer certificate
  12. ThreadLocal理解
  13. JavaScript判断数组的几种方法
  14. 大数据时代没有隐私,我们都在裸奔
  15. APP产品经理(一)
  16. python创建数据库字数不限制_KindEditor设置字数限制
  17. git did not exit cleanly(exit code 128)报错的部分原因及解决方法
  18. DSP28035控制舵机
  19. 计算机文件丢失系统无法启动,文件损坏或丢失windows无法启动_windows无法启动文件损坏解决方法...
  20. mvn compile报错“程序包com.XXX不存在”

热门文章

  1. linux动态分配全局置换,深入理解计算机系统 第九章 虚拟存储器
  2. Python三元运算
  3. python中函数的括号使用
  4. python声音分类_Python音频信号分类MFCC特征神经网络
  5. oracle instead of update触发器,Oracle中的instead of触发器
  6. VMWare虚拟机打不开、繁忙无法关闭、不可恢复错误(mks)(不要在虚拟机下用win+L锁屏,不然就繁忙。。。)
  7. C语言 泛型链表 如何计算(结构体中各元素)相对内存地址?(字节对齐,结构体对齐)offsetof()函数 ( (struct X*)0 ) -> Y)语法(匿名结构体)
  8. Github 代码上边的Raw、Blame、History是啥意思?
  9. python sklearn.decomposition.PCA 主成分分析, 原理详解
  10. 蓝桥杯C++ AB组辅导课 第二讲 二分与前缀和 Acwing