测试开发之函数进阶递归函数
目录
一、往期回顾 1.生成器代码详解 2.生成器的三个方法
二、递归函数 1.什么是递归函数 2.递归函数调用原理图 3.递归边界 4.通过递归函数实现的任意数的阶乘 5.这个递归函数的递归临界点在哪? 6.斐波那契数列
三、系列推荐 1.生成器代码详解def gen(): for i in range(5): j = yield i print(j) # send:与生成器进行交互 g = gen() print(next(g)) print(next(g))
第一个 print(next(g)) 打印的 0,就是生成器生成的元素。第二个print(next(g)) 打印的 1 也是生成器生成的元素,None 是print(j) 打印的j 。
通过生成器获取元素的时候,首先生成器进去的话,当调用生成器获取里面的值,它会从上往下走,走到 j = yield i 这里,把yield 这里的i 这个值返回出来,调用完gen() 返回一个生成器g 。
通过这个生成器 next(g) 去拿值的时候,然后它从上往下执行代码,走到j = yield i 这里,yield 相当于把i ,通过yield 返回出去。
从生成器里面返回出来,就生成一个数据。生成这个 i ,到第一个print(next(g)) 这里,打印的就是i 。
第二个 print(next(g)) ,再用next() 调用生成器的时候,那么这个生成器会从yield 之后继续往下执行。
通过 next() 去触发生成器的时候,yield 之后是没有内容的,j 接收的就是空的,所以打印j 的时候,打印出来的是个None 。 2.生成器的三个方法# 生成器的三个方法:send close throw def gen(): for i in range(5): j = yield i print(j) # send:与生成器进行交互 g = gen() print(g.send(100)) print(next(g)) print(next(g))
运行后报错:
生成器的 send() 方法,它运行的时候会从上一个yield 结束的地方来进行运行。
在这里只创建了 gen() 这个生成器,这个生成器还没有生成过任何数据,这个时候生成器就暂停在函数最开始的地方def gen(): 这里。
这里 send(100) 这个值进去的话,在这里运行,直接运行for i in range(5): 这个语句,send(100) 生成进去的这个值没有地方接收,所以报错了。
send() 必须在调用了一次next() 之后才调用。可以和next() 一样,去获取生成器里面的内容。 2.1next()获取生成器里面的内容:# 生成器的三个方法:send close throw def gen(): for i in range(5): j = yield i print(j) # send:与生成器进行交互 g = gen() print(next(g)) print(next(g)) # print(g.send(100))
2.2send()在调用了一次next()之后调用,获取生成器里面的内容:# 生成器的三个方法:send close throw def gen(): for i in range(5): j = yield i print(j) # send:与生成器进行交互 g = gen() print(next(g)) print(g.send(100)) # print(next(g))
yield 只能在函数里面用。yield 关键字是用在创建生成器的时候,只要函数里面使用了yield 关键字,在调用函数的时候,函数不会立马被执行。
因为这个函数不是简单的函数了,它是个生成器。
在函数外面,是没办法用 yield 关键字的。
2.3close():关闭生成器def gen(): for i in range(5): j = yield i print(j) yield 100 # send:与生成器进行交互 g = gen() print(next(g)) # print(next(g)) # print(g.send(100)) # close:关闭生成器 g.close() print(next(g))
2.4throw()方法:在生成器内部主动引发一个异常。参数:1.异常类型。2.异常信息。
这个方法可以接收 2 个参数,第一个参数: Exception 异常类型。第二个参数:传入异常的信息。
Exception 报错:
g.throw(Exception,"Method throw called!")
ValueError:
g.throw(ValueError,"清菡,大事不好,报错了,嘤嘤嘤~")
二、递归函数1.什么是递归函数
在函数中调用函数自身,我们把这样的函数叫做递归函数。 2.递归函数调用原理图
递归函数调用自身 3.递归边界
递归边界: 退出递归的终止条件。 def func(): print("99999") func() func()
在外面调用函数,直接陷入一个死循环。在函数内部调用 func() 这个函数,又到def func(): 这里来执行,然后print("99999") ,又func() 调用。
不断得自身调用,这样就造成了死循环。
Pycharm 有个检测机制: 当它内部检测到这个是个无限递归,没有递归临界点的一个递归函数,那么这个时候,它递归多少次之后,会自动给终止了。
使用递归函数的时候,一定要注意一个点: 就是一定要设置递归的边界。递归的边界就是递归函数的终止条件。
如果你不设置递归边界,那么你定义的递归函数就是个死循环,一直无限得调用自身。 4.通过递归函数实现的任意数的阶乘4.1 什么是阶乘?
1 的阶乘1 2 的阶乘1*2 3 的阶乘1 * 2 * 3 4 的阶乘1 * 2 * 3 * 4
递归能实现的,通过循环都能实现。
Python 中递归用得不多,不太建议使用递归,因为递归不太好用,用递归还不如用循环。 4.2 怎么去算阶乘呢?
定义个函数,算任意数的阶乘。传 1,就算 1 的阶乘,传 10 就算 10 的阶乘。
可以这样做:
首先要判断下它传进来的这个参数是不是等于 1,如果是等于 1 的话,就直接给它 return 返回出去。然后,如果它不等于 1 的话,就返回return n * (n-1)*(n-2) 。
n 传进来是 1,那应该返回 1;如果传的是 2,应该返回 return n * (n-1) 。
如果在这里用递归函数,调用 func(1) 。那么这个时候,这个func(1) 调用递归函数。
这个函数返回的是什么?
调用这段代码: if n == 1: return 1
返回的是个 1。
将代码修改成如下: def fun(n): if n == 1: return 1 else: return n * fun(n-1) fun(3)
如果是 fun(3) ,3 传进来: def fun(n): if n == 1: return 1
肯定是不成立的。
else 后面的代码return n * fun(n-1) 。
这里的 n 是个 3, fun(n-1) 就是fun(2) ,那么就是3 * fun(2) 。
这个时候会再次调用自身这个函数:
这个时候 n 是什么?
fun(2) 的时候 n 是个 2,就是3 *2* fun(1) 。fun(1) 再执行下,出来的结果是个 1。那这里就是个 1,就是3*2*1 。
等于 3 的时候,返回的结果就是 3*2*1 。 4.3 改成fun(4)看看:
首先 4 进来,n 等于 4, fun(n-1) 就是fun(3) 。调用fun(3) 就相当于再次调用fun(n) ,就是4 *3* fun(2) 。
再次调用 fun(2) ,再进来,前面return n * fun(n-1) 这一截得到 2,fun(3-1) 得到 2,所以最终得到4*3*2* fun(1) 。
fun(1) 调用,结果出来就是个 1。就是4*3*2*1 。 def fun(n): if n == 1: return 1 else: return n * fun(n-1) # 4 *3*2*1 fun(4)5.这个递归函数的递归临界点在哪? if n == 1: return 1
当 n=1 的时候就不会调用自身了。当满足某个条件,不再调用自身,那么这个就被称为递归临界点。
例如改成 n==-1 if n == -1: return 1
这个时候,这个函数的递归临界点在哪?
这个递归临界点就是 -1 。 def fun(n): if n == -1:# 递归临界点:当达到递归临界点的时候,就不再调用自身函数的条件 return 1 else: return n * fun(n-1) # 4 *3*2*1 fun(4)
任何递归函数,它的原理都是一样的。定义一个递归函数,在递归函数里面它其实就是不断得调用自身,然后设置递归函数的时候,一定不能忘了递归条件。 6.斐波那契数列
后面的数都是等于前 2 个数相加的结果。
斐波那契数列的第一个数值是 1,第二个数值也是个 1,第三个数等于前两个数相加的结果(那就是 2),第四个数等于于前两个数相加的结果(那就是 3)。
[1,1,2,3,5]
以此类推。
去云南必备的20条建议云南中国最舒适的地方之一。为什么去云南玩呢?首先,云南天气不冷不热其次,那就是云南美啊!云南很大很美,现在去云南的朋友也越来越多。如果你想去云南,赶紧收藏这20条建议吧!1。如果你
剧透!2021宝德数字产业生态大会亮点抢先看11月10日,以新生态同命运共发展为主题的2021宝德数字产业生态大会即将在深圳博林天瑞喜来登酒店正式开幕。据悉,本次峰会由一场主论坛,三场分论坛组成,汇聚政府领导工信部领导专家领
多维度对比分析哪些进口奶粉品牌值得推荐现在,越来越多的进口奶粉涌入中国市场,一方面为父母提供了多样化的选择空间,但也增加了选择的难度。尽管一部分中国宝妈已经有挑选进口奶粉的经验,但市场上的进口奶粉质量参差不齐,如何挑选
电池1无法充电,提示维修,MacBookPro电池门爆发MacBookPro电池电量提示1,建议维修,且无法充电!最近遇到这个问题,网上一看集中爆发了好多!开始以为是天冷电池损耗多,或者过冷电池保护导致,后来发现不是。罪魁祸首应该是苹果
宝妈心目中的优质进口奶粉这些优点必不可少婴幼儿配方奶粉在宝宝成长的过程中占有重要地位,营养健康品质优良的奶粉,自然得到宝妈们的喜爱。为了给下一代提供更丰富的营养选择,父母们在挑选奶粉的时候也越来越仔细。现在国内市场上,进
带货最高超2。5亿,企业家也能变网红OMG这也太好看了吧买它买它买它2019年,被称为网红经济元年,李佳琦薇娅张大奕等头部网红,不仅带货成绩惊人,而且频频出圈,获得不低于明星的关注。在网红之外,直播带货行业崛起了一股
新疆美景对比瑞士风光,哪个更美?新疆面积166万平方公里,瑞士面积4。1284万平方公里,新疆面积是瑞士的40倍。新疆最大的县是若羌县,面积20万平方公里,是瑞士的5倍。在新疆,你可以看到草原雪山戈壁荒漠冰川湖泊
抢先体验,看看ColorOS12升级了什么经过这几年的技术迭代,国产定制系统已经有了很不错的水平,彻底撕掉过去卡顿不好看标签,比如OPPO的ColorOS系统,所主打的无边界设计理念就很受消费者的欢迎,月活用户更是突破3。
平板新星!荣耀平板V7Pro正式开售,这售价和配置赚到了在8月12日的荣耀发布会上,荣耀平板V7Pro也正式亮相,随着时间来到8月19日,这款平板也迎来了开售,售价为2599元起。来说说荣耀平板V7Pro的配置吧首先正面是一块11英寸大
领衔国产品牌再创佳绩,OPPO销量全球第二,这些爆款产品功不可没现如今,越来越多的人意识到5G潮流是大势所趋,在5G时代下,各行各业都迎来了加速发展,5G手机产品更是快速渗透。根据9月13日国新办召开的发布会所公开的数据显示,今年1至8月,国内
红魔游戏手机6SPro发布倒计时,拉满的游戏体验还会有多少惊喜?还有一天的时间,红魔游戏手机6SPro就要发布了,其实在这些天的预热里,关于红魔游戏手机6SPro的一些亮点我们已经可以提前知道了,现在就让我们来做一个盘点,方便大家提前判断。就先