python函数递归求和详解_Python递归函数详细分析

article/2025/10/24 16:29:52

什么是递归?

递归,就是在函数运行中自己调用自己

代码示例:

def recursion(n): # 定义递归函数

print(n) # 打印n

recursion(n+1) # 在函数的运行种调用递归

recursion(1) # 调用函数

这个函数在不断的自己调用自己,每次调用n+1,看下运行结果:

1

2

.....

998Traceback (most recent call last):

File "D:/py_study/day08-函数/Python递归函数md/01-什么是递归.py", line 11, in

recursion(1)

File "D:/py_study/day08-函数/python递归函数md/01-什么是递归.py", line 9, in recursion

recursion(n+1)

File "D:/py_study/day08-函数/python递归函数md/01-什么是递归.py", line 9, in recursion

recursion(n+1)

File "D:/py_study/day08-函数/python递归函数md/01-什么是递归.py", line 9, in recursion

recursion(n+1)

[Previous line repeated 993 more times]

File "D:/py_study/day08-函数/python递归函数md/01-什么是递归.py", line 8, in recursion

print(n)

RecursionError: maximum recursion depth exceeded while calling a Python object

Process finished with exit code 1

可为什么执行了900多次就报错了呢?还说超过了最大递归深度限制,为什么要限制呢?

通俗来讲,是因为每个函数在调用自己的时候,还没有退出,占内存,多了肯定会导致内存崩溃.

本质上来将,在计算机中,函数调用是通过栈(stack)这样数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会少一层栈帧.由于栈的大小不是无限的,所以,递归调用次数多了,会导致栈溢出.

我们还可以修改递归深度,代码如下:

import sys

sys.setrecursionlimit(1500) # 修改递归调用深度

def cacl(n):

print(n)

cacl(n+1)

cacl(1)

运行结果如下:

1

2

......

1498Traceback (most recent call last):

File "D:/py_study/day08-函数/python递归函数md/02-修改递归深度.py", line 11, in cacl

cacl(n+1)

File "D:/py_study/day08-函数/python递归函数md/02-修改递归深度.py", line 11, in cacl

cacl(n+1)

File "D:/py_study/day08-函数/python递归函数md/02-修改递归深度.py", line 11, in cacl

cacl(n+1)

[Previous line repeated 995 more times]

File "D:/py_study/day08-函数/python递归函数md/02-修改递归深度.py", line 10, in cacl

print(n)

RecursionError: maximum recursion depth exceeded while calling a Python object

让我们以最经典的例子说明递归

# 计算n! # 相信很多人都学过阶乘,比如5! = 5*4*3*2*1 n! = n*(n-1)*(n-2)*...*1,那么在递归中该如何实现呢?

# 1.打好函数的框架

def factorial(n): # 定义一个计算阶乘的函数

pass # 不做任何操作

factorial(3) # 调用

# 2.考虑两种情况,如果n=1,那么1的阶乘就是1了,如果这个传递的参数大于1,那么就需要计算继承了.

def factorial(n):

if n == 1: # 判断如果传递的参数是1的情况

return 1 # 返回1,return代表程序的终止

res = factorial(1) # res变量来接受函数的返回值

print(res) # 打印

2.1如果传递的参数不是1,怎么做?

def factorial(n):

if n == 1:

return 1

else:

# 5*4! = 5*4*3! = 5*4*3*2!

return n * factorial(n-1) # 传递的参数是n,那么再次调用factorial(n-1)

res = factorial(1)

print(res)

举例2:

# 让10不断除以2,直到0为止。

int(10/2) = 5

int(5/2) = 2

int(2/2) = 1

int(1/2) = 0

# 1.同样第一步先打框架

def cacl(n): # 定义函数

pass

cacl(10)

# 2.那么我们想从10开始打印然后一直到0,怎么做?

def cacl(n): # 定义函数

print(n)

cacl(10)

# 3.已经把打印的值传递进去了,那么就是在里面操作了

def cacl(n): # 定义函数

print(n) # 打印传递进去的值

v = int(n /2) # n/2

if v>0: # 如果v还大于0

cacl(v) # 递归,把v传递进去

print(n) # 打印v,因为已经调用递归了,所以此时的n是v

cacl(10)

运行结果如下:

10

5

2

1

1

2

5

10

怎么输出会是这样呢?我刚刚说过,什么是递归?递归就是在一个函数的内部调用函数本身,我们打个比方,递归一共有3层,那么第二层就是调用第一层的结果,第三层又去调用第二层的结果,所以!当上面这个程序运行时,第一次打印的是10,然后除上2,等于是5,再继续除,一直到了1,然后1/2是等于0的,此时就没有调用了递归,但是我还在调用上一层函数,就需要把这个数给返回出来,所以就变成后来的1,2,5,10了。

递归特性

•1.必须要有一个明确的结束条件, 否则就变成死循环导致栈溢出

•2.每次进入更深一层递归时,问题规模相比上次递归都应有所减少,这句话的以上就是说,每进入一次递归,就会解决一些东西,数据量就会越来越小,最终解决了所有的问题,如果进入一次递归没有解决问题,那么不管递归多少层都没有意义,直到导致栈溢出。

•3.递归效率比较低,递归层次过多会导致栈溢出,意思是:每当进入一次函数调用,栈就会加一层栈帧,每当函数返回,就减少一层栈帧,由于栈不是无限大小的,所以,递归调用的次数过多,会导致栈溢出。

那么有没有优化方式呢?肯定是有的

尾递归

我在知乎上找了一个特别有意思的例子来说明下什么是尾递归:

def story() {

从前有座山,

山上有座庙,

庙里有个老和尚,

一天老和尚对小和尚讲故事:story() // 尾递归,进入下一个函数不再需要上一个函数的环境了,得出结果以后直接返回。

}

def story() {

从前有座山,

山上有座庙,

庙里有个老和尚,

一天老和尚对小和尚讲故事:story(),小和尚听了,找了块豆腐撞死了 // 非尾递归,下一个函数结束以后此函数还有后续,所以必须保存本身的环境以供处理返回值。

}

尾递归,进入下一个函数不再需要上一个函数的环境了,得出结果以后直接返回。

def cal(n):

print(n)

return cal(n+1) # return代表函数的结束

cal(1) # 这个会一直打印,直到导致栈溢出

# 调用下一层的同时,自己就退出了

logo.gif


http://chatgpt.dhexx.cn/article/j5kRE0Qy.shtml

相关文章

Python递归思想与代码实现

1, 递归思想 递归算法:递归(Recursion),在数学与计算机科学中,是指在函数的定义中使用函数自身的方法。 这是官方的解释,翻译成人话就是: 函数内部自己调用自己函数必须有出口 函数自己调用自己很好理解&#xff0c…

python函数递归调用时对深度没有限制_python递归深度

广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 今天在写爬虫的时候,发现了一个事情,使用str方法强制转换一个beautifulsoup对象成字符串的时候报错了,提示是“maximum recursion depth exceeded while cal…

python递归函数详解

python递归函数是指一个函数从一个状态开始,然后返回另一个状态。递归函数是在实现过程中遇到的最基本的一类函数。比如, int i0; int j0; int c1;等等都是一类递归函数,但是我们知道,它们在实现过程中需要执行多次,并…

Python 递归的优化

文章目录 前言一、递归实现斐波那契二、优化后的斐波那契总结 前言 递归,很常见的一种算法,在初学的时候我们都会用递归来解决斐波那契数列,但递归本身有非常大的缺陷,就是时间和空间占用都非常大,在进阶学习后&#…

Python 递归实现乘法

Python定义函数:使用递归求乘积(x*y) 1 当作x个y相加或者y个x相加 2 当其中一数(以x为例)不为1时,返回y加上该函数,同时每次x-1,直至x1为止,此过程实现了x个y相加 具体代码如下:

python递归遍历查询文件 文件夹

文章目录 🍗先看运行效果🍔 具体思路🍟 一、主要使用的模块以及方法🌭 二、主要思路以及代码🍿 1、开始位置🧂 2、关键位置🥓 3、结果输出 🧇 完整源码🥞 结尾&#x1f9…

轻松搞懂Python递归函数的原理与应用

递归: 在函数的定义中,函数内部的语句调用函数本身。 1、递归的原理 学习任何计算机语言过程中,“递归”一直是所有人心中的疼。不知你是否听过这个冷笑话:“一个面包,走着走着饿了,于是就把自己吃了”。 常理推断&…

python递归如何理解

最近在做递归一些相关的东西,发现递归入门很容易,但要具体了解其实现过程,比较难以理解,在这里将自己这几天的摸索记录一下,写知乎的主要目的是为了给自己做笔记,在做笔记的同时,帮助后来人少走…

【Python函数的递归】

递归的定义 函数作为一种代码封装,可以被其他程序调用,当然,也可以被函数内部代码调用。这种函数定义中调用函数自身的方式称为递归。就像一个人站在装满镜子的房间中,看到的影像就是递归的结果。递归在数学和计算机应用上非常强大…

H3C 交换机S5130S软件版本升级

1.通过官网下载软件包 升级的包名为 S5130S_HI-CMW710-R6330.ipe 2. 查看FLASH空间是否足够 <H3C>dir /all Free的空间需要是软件包的2倍大小&#xff0c;例如S5130S_HI-CMW710-R6330.ipe软件包大小为54MB&#xff0c;那么交换机Free的空间需要108M。 空间如果…

H3C 交换机S6520X软件版本升级

1.通过官网下载软件包 升级的包名为 S6520X-CMW710-R6312P02.zip 压缩包里有很多特性包&#xff0c;我们目前就使用 S6520X-CMW710-R6312P02.ipe 2. 查看FLASH空间是否足够 <H3C>dir /all Free的空间需要是软件包的2倍大小&#xff0c;例如S6520X-CMW710-R6312P0…

H3c服务器升级硬盘固件,H3C交换机升级固件版本

二、进入产品支持与服务&#xff0c;找到适配的交换机固件进行下载 三、下载时要求提供用户名密码 用户名&#xff1a;yx800 密码&#xff1a;01230123 四、H3C官方升级说明案例 1.1 实验拓扑(假设SW1上 VLAN 1 的虚地址为10.10.10.1&#xff0c;PC配置同网段地址10.10.10.…

博途V16 更改PLC的型号和固件版本

在线访问&#xff0c;查看硬件PLC的固件版本。 右键&#xff0c;选择更改设备。 选择PLC型号和版本号。

TIA博途_如何更新程序中的指令版本和CPU固件版本?

TIA博途_如何更新程序中的指令版本和CPU固件版本? TIA博途STEP7从V14SP1版本增加新功能:“更新程序”,可以将当前CPU中的程序版本更新至能够使用的最高版本,对于通讯、运动控制等版本经常升级的程序非常适用, 以下进行举例说明: TIA博途STEP7 V13 SP1中组态S7-1200 V4.1版…

TIA PORTAL西门子PLC的CPU固件版本兼容问题

TIA PORTAL西门子PLC的CPU固件版本兼容问题 以S7-1200为例&#xff0c;现在新出的PLC的固件都是V4.4的版本了&#xff0c;而原来的软件如V15.0组态不到V4.4&#xff0c;只能组态到V4.2&#xff0c;在想继续使用V15.0的情况下&#xff0c;这个PLC还可以用吗&#xff1f; 答案是可…

如何在TIA博途中在线更新PLC的CPU固件版本?

如何在TIA博途中在线更新PLC的CPU固件版本? S7-1200PLC最新的V4.6.0版本的固件出来了,本次就以V4.6版本的固件为例,演示如何在博途中对PLC的固件版本进行更新。 (为防止更新过程中出现意外,强烈建议对PLC的程序进行备份!备份!备份!) 如下图所示,打开某个项目,选中PL…

西门子S7-1200如何使用TIA软件更新CPU固件版本

1、先点击上方“可访问的设备”按钮&#xff0c;扫描出当前所连PLC。 2、点击“显示”&#xff0c;在右边目录树中即可显示出所连PLC&#xff0c;点击“在线和诊断”。 3、即可显示出固件版本和上一个使用者所用博图软件版本。 4、打开所连接S7-1200的“在线和诊断”视图&…

软件版本控制流程

1.编写目的 主要针对软件版本的流程, 以确保公司资产得到保护。 2.适用范围 该流程适用于产品研发部门。 3.环境资源 在整个产品生命周期中&#xff0c;以gitlab作为公司主要代码仓库。 4.流程 流程分为版本号定义、版本发布 4.1 版本号定义 4.1.1 版本号规则 采用语义…

康耐视智能相机更新固件版本方式

康耐视智能相机更新固件版本方式 1、 首先下载对应版本的in-sight Explorer软件&#xff0c;软件自带此版本的固件信息 2、 打开软件&#xff0c;将相机与电脑处于同一网段&#xff0c;在系统—将传感器/设备添加到网络 3、 设置好相机的IP 地址 4、 确认相机与电脑在同一网…

keil中查看仿真器固件版本号

1.首先选择仿真器类型 2.然后点击设置&#xff0c;FW Version显示的就是版本号。