一、函数执行流程

示例.png

全局帧中生成 foo1、foo2、foo3、main 函数对象

main 函数调用

main 中查找内建函数 print 压栈,将常量字符串压栈,调用函数,弹出栈顶

main 中全局查找函数 foo1 压栈,将常量 100、101 压栈,调用函数 foo1,创建栈帧。print 函数压栈,字符串和变量 b、b1 压栈,调用函数,弹出栈顶,返回值

main 中全局查找函数 foo2 压栈,将常量 200 压栈,调用函数 foo2,创建栈帧。foo3 函数压栈,变量 c 引用压栈,调用 foo3,创建栈帧。foo3 完成 print 函数调用后返回。foo2 恢复调用,执行 print 后,返回值。main 中 foo2 调用结束弹出栈顶。main 继续执行 print 函数调用,弹出栈顶。main 函数返回

示例.png

示例.png

二、递归 Recursion

函数直接或见着调用自身就是 递归

递归需要有边界条件、递归前进段、递归返回段

递归一定要有 边界条件

当边界条件不满足的时候,递归前进

当边界条件满足的时候,递归返回

示例.png

2.1 斐波那契数列 Fibonacci number:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ....

若 F(n) 为该数列第 n 项(n∈N*),那么这句话可写成:F(n)=F(n-1)+F(n-2)

F(0)=0, F(1)=1, F(n)=F(n-1)+F(n-2)

a = 0

b = 1

n = 10 # 55

# 循环实现

for i in range(n -1):

a, b = b, a + b

else:

print(b)

# 递归实现

def fib(n):

return 1 if n < 3 else fib(n-1) + fib(n-2)

fib(5) 解析

fib(4) + fib(3)

fib(4) 调用 fib(3)、fib(2)

fib(3) 调用 fib(2)、fib(1)

fib(2)、fib(1) 是边界 return 1,所有函数调用逐层返回

2.2 递归要求

递归一定要有退出条件,递归调用一定要执行到这个退出条件。没有退出条件的递归调用,就是无限调用

递归调用的深度不宜过深

Python 对递归调用的深度做了限制,以保护解释器

超过递归深度限制,抛出 RecursionError: maxinum recursion depth exceeded 超出最大深度

sys.getrecursionlimit()

2.3 递归性能 fib(35) 比较

for 循环

示例.png

递归

示例.png

2.4 递归的性能

循环稍微复杂一些,但是只要不是死循环,可多次迭代直至算出结果

fib 函数代码极简易懂,但是只能获取到最外层函数调用,内部递归结果都是中间结果。而且给定一个 n 都要进行近 2n 次递归,深度越深,效率越低。为了获取斐波那契数列需要外面再套一个 n 次循环,效率就更低了

递归还有深度限制,若递归复杂,函数反复压栈,栈内存很快就溢出了

斐波那契数列改进

def fib(n, a=0, b=1):

a, b = b, a+b

if n == 1:

return a

return fib(n-1, a, b)

print(fib(4))

改进后的函数和循环的思想类似

参数 n 是边界条件,用 n 来计数

上次的计算结果直接作为函数的实参

效率高

和循环比较,性能相近。所以并不是说递归一定效率低下,但递归有深度限制

2.5 间接递归

def foo1():

foo2()

def foo2():

foo1()

foo1()

间接递归,是通过别的函数调用了函数自身

拖构成了循环递归调用是非常危险的,但往往这种情况在代码复杂情况下,很可能发生这种调用,要用代码的规范来避免递归调用的发生

三、递归总结

递归是一种很自然的表达,符合逻辑思维

递归相对运行效率低,每一次调用函数都要开辟栈帧

递归有深度限制,若递归层次太深,函数反复压栈,栈内存很快就溢出了

若是有限次数的递归,可使用递归调用,或使用循环代替,循环代码稍复杂一些,但只要不是死循环,可多次迭代直至算出结果

绝大多数递归,都可使用循环实现

即使递归代码很简洁,但 能不用则不用 递归

四、递归练习

4.1 求 n 的阶乘

按公式

def fac(n):

if n == 1:

return 1

return n * fac(n-1)

def fac(n):

return 1 if n < 2 else n * fac(n-1)

按循环

n = 6

fac = 1

for i in range(n, 0, -1): # 计数器 n 次

fac = fac * i

print(fac)

def fac1(n, fac=1):

fac = fac * n

if n == 1:

return fac

return fac1(n-1, fac)

4.2 将一个数逆序放入列表中,例如 1234 => [4, 3, 2, 1]

传入字符串

target = []

def revert(data):

target.append(data[-1])

if len(data) == 1:

return target

return revert(data[:-1])

revert('1234')

def revert(data, target=None):

if target is None:

target = list()

target.append(data[-1])

if len(data) == 1:

return target

return revert(data[:-1], target)

revert('1234')

def revert(data):

if data == '':

return []

return [data[-1]] + revert(data[:-1])

revert('1234')

传入数字

def revert(data, target=None):

if target is None:

target = list()

if not isinstance(target, list):

return

x, y = divmod(data, 10)

target.append(y)

if x:

return revert(x, target)

return target

revert(120340)

4.3 解决猴子吃桃问题

按题意

def peach(days=1):

if days == 10:

return 1

return 2 * (peach(days+1) +1)

def peach(days=10):

if days == 1:

return 1

return 2 * (peach(days-1) + 1)

按循环

peach = 1

for i in range(9):

peach = 2 * (peach + 1)

print(peach)

def fn(days=9, peach=1):

peach = 2 * (peach + 1)

if days == 1:

return peach

return fn(days-1, peach)

fn()

python递归函数的意思_Python 递归函数相关推荐

  1. python中递归函数的实例_Python 递归函数详解及实例

    Python 递归函数 如果一个函数体直接或者间接调用自己,那么这个函数就称为递归函数.也就是说,递归函数体的执行过程中可能会返回去再次调用该函数.在python里,递归函数不需要任何特殊的语法,但是 ...

  2. python递归函数的思想_Python递归函数实例讲解

    Python递归函数实例 1.打开Python开发工具IDLE,新建'递归.py'文件,并写代码如下: def digui(n): if n == 0 : print ('') return prin ...

  3. python 递归 写平方_Python递归函数如何写?正确的Python递归函数用法

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是 ...

  4. python递归函数入门教程_Python递归函数

    在函数内部,还可以调用其他函数,比如实现函数data_of_square的时候,它接收边长一个参数,同时返回正方形的周长和面积,而求周长和求面积是完全独立的逻辑,可以定义成两个新的函数,然后在data ...

  5. python中的递归函数如何表示_python:递归函数

    在函数内部我们可以调用其它函数如: defsay(great):returngreatdefperson(name):print(say("Hello"), name) perso ...

  6. python 画树 递归_python递归函数绘制分形树的方法

    分形几何学的基本思想:客观事物具有自相似性的层次结构,局部和整体在形态,功能,信息,时间,空间等方面具有统计意义上的相似性,称为自相似性,自相似性是指局部是整体成比例缩小的性质. 我们先看一下我们最终 ...

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

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

  8. [转载] 递归函数python基例_python递归函数详解 python 递归函数使用装饰器

    参考链接: Python递归 移动宽带检查显示 CRM,radius状态不一致是怎么回事啊?您可以把电信宽带猫等设备重启试一下,如果仍然不行,可以拨打10000号请工作人员帮您查看.处理. 电信宽带诊 ...

  9. vscode使用教程python-VSCode下好用的Python插件及配置_python

    这篇文章主要介绍了微软官方的Python插件,已经自带很多功能,下面是插件功能描述,其中部分内容我做了翻译,需要的朋友可以参考下 MS Python插件. 这是微软官方的Python插件,已经自带很多 ...

最新文章

  1. @RequestMapping报404错误问题解决
  2. linux 安装 mysql 5.6_Linux安装MySQL_5.6
  3. 火了!女教授把自己P成女娲,登上学术期刊封面
  4. python request url 转义_Python爬虫入门笔记
  5. Linux中解压解压rar文件
  6. ESLint 规则详解(二)
  7. Oracle监听器无法启动
  8. java创新创业比赛项目教程_java毕业设计_springboot框架的大学生创新创业项目管理...
  9. SD卡fat32文件格式说明
  10. 4.8 HD-GR GNSS导航软件源码
  11. go-优雅地重启http服务之endless
  12. 阿里云ECS节省计划重磅发布 比包年包月灵活,比按量付费划算,最高节省76%费用
  13. 手机厂商要和年轻人交朋友,性价比日渐式微?
  14. python3爬取教务系统的个人学期课程表(无头谷歌浏览模拟登录)
  15. Xmanager或者Xshell用户连接信息迁移
  16. java给文件777权限_Linux常用命令:chmod修改文件权限 777和755分别是什么意思?
  17. 分式化简结果要求_分式约分的结果是()
  18. 机器学习中,什么是线性和非线性?
  19. android控制电路板的开关灯,一文解读LED触摸调光台灯控制电路板的工作原理
  20. 精易编程助手在win10网页不能分析,显示无法访问该页只解决方法

热门文章

  1. dojo.publish 和 dojo.subscribe
  2. 自定义的注解校验器的实现
  3. 修改Apache的默认站点目录的方法,需要的朋友可以参考下
  4. 小技巧:让linux程序在后台运行
  5. 并发编程—Volatile关键字
  6. Windows Server 2012 新特性:IPAM的配置
  7. 虚拟化模板新建虚拟机后 wsus控制台无法看到所有客户端计算机
  8. 形参与实参, 值传递与引用传递, ref参数与out参数的区别和联系?
  9. 图形图像显示研究(一)
  10. 卸载Internet Explorer 7 Beta 2 Preview引起原来的IE无法正常使用