1。生成器代码详解defgen():foriinrange(5):jyieldiprint(j)send:与生成器进行交互ggen()print(next(g))print(next(g)) 第一个print(next(g))打印的0,就是生成器生成的元素。第二个print(next(g))打印的1也是生成器生成的元素,None是print(j)打印的j。 通过生成器获取元素的时候,首先生成器进去的话,当调用生成器获取里面的值,它会从上往下走,走到jyieldi这里,把yield这里的i这个值返回出来,调用完gen()返回一个生成器g。 通过这个生成器next(g)去拿值的时候,然后它从上往下执行代码,走到jyieldi这里,yield相当于把i,通过yield返回出去。 从生成器里面返回出来,就生成一个数据。生成这个i,到第一个print(next(g))这里,打印的就是i。 第二个print(next(g)),再用next()调用生成器的时候,那么这个生成器会从yield之后继续往下执行。 通过next()去触发生成器的时候,yield之后是没有内容的,j接收的就是空的,所以打印j的时候,打印出来的是个None。2。生成器的三个方法生成器的三个方法:sendclosethrowdefgen():foriinrange(5):jyieldiprint(j)send:与生成器进行交互ggen()print(g。send(100))print(next(g))print(next(g)) 运行后报错: 生成器的send()方法,它运行的时候会从上一个yield结束的地方来进行运行。 在这里只创建了gen()这个生成器,这个生成器还没有生成过任何数据,这个时候生成器就暂停在函数最开始的地方defgen():这里。 这里send(100)这个值进去的话,在这里运行,直接运行foriinrange(5):这个语句,send(100)生成进去的这个值没有地方接收,所以报错了。 send()必须在调用了一次next()之后才调用。可以和next()一样,去获取生成器里面的内容。2。1next()获取生成器里面的内容:生成器的三个方法:sendclosethrowdefgen():foriinrange(5):jyieldiprint(j)send:与生成器进行交互ggen()print(next(g))print(next(g))print(g。send(100)) 2。2send()在调用了一次next()之后调用,获取生成器里面的内容:生成器的三个方法:sendclosethrowdefgen():foriinrange(5):jyieldiprint(j)send:与生成器进行交互ggen()print(next(g))print(g。send(100))print(next(g)) yield只能在函数里面用。yield关键字是用在创建生成器的时候,只要函数里面使用了yield关键字,在调用函数的时候,函数不会立马被执行。 因为这个函数不是简单的函数了,它是个生成器。 在函数外面,是没办法用yield关键字的。 2。3close():关闭生成器defgen():foriinrange(5):jyieldiprint(j)yield100send:与生成器进行交互ggen()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,Methodthrowcalled!) ValueError: g。throw(ValueError,清菡,大事不好,报错了,嘤嘤嘤) 二、递归函数1。什么是递归函数 在函数中调用函数自身,我们把这样的函数叫做递归函数。2。递归函数调用原理图 3。递归边界 递归边界:退出递归的终止条件。deffunc():print(99999)func()func() 在外面调用函数,直接陷入一个死循环。在函数内部调用func()这个函数,又到deffunc():这里来执行,然后print(99999),又func()调用。 不断得自身调用,这样就造成了死循环。 Pycharm有个检测机制:当它内部检测到这个是个无限递归,没有递归临界点的一个递归函数,那么这个时候,它递归多少次之后,会自动给终止了。 使用递归函数的时候,一定要注意一个点:就是一定要设置递归的边界。递归的边界就是递归函数的终止条件。 如果你不设置递归边界,那么你定义的递归函数就是个死循环,一直无限得调用自身。4。通过递归函数实现的任意数的阶乘4。1什么是阶乘? 1的阶乘 1hr2的阶乘 12 3的阶乘 123 4的阶乘 1234 递归能实现的,通过循环都能实现。 Python中递归用得不多,不太建议使用递归,因为递归不太好用,用递归还不如用循环。4。2怎么去算阶乘呢? 定义个函数,算任意数的阶乘。传1,就算1的阶乘,传10就算10的阶乘。 可以这样做: 首先要判断下它传进来的这个参数是不是等于1,如果是等于1的话,就直接给它return返回出去。然后,如果它不等于1的话,就返回returnn(n1)(n2)。 n传进来是1,那应该返回1;如果传的是2,应该返回returnn(n1)。 如果在这里用递归函数,调用func(1)。那么这个时候,这个func(1)调用递归函数。 这个函数返回的是什么? 调用这段代码:ifn1:return1 返回的是个1。 将代码修改成如下:deffun(n):ifn1:return1else:returnnfun(n1)fun(3) 如果是fun(3),3传进来:deffun(n):ifn1:return1 肯定是不成立的。 else后面的代码returnnfun(n1)。 这里的n是个3,fun(n1)就是fun(2),那么就是3fun(2)。 这个时候会再次调用自身这个函数: 这个时候n是什么? fun(2)的时候n是个2,就是32fun(1)。fun(1)再执行下,出来的结果是个1。那这里就是个1,就是321。 等于3的时候,返回的结果就是321。4。3改成fun(4)看看: 首先4进来,n等于4,fun(n1)就是fun(3)。调用fun(3)就相当于再次调用fun(n),就是43fun(2)。 再次调用fun(2),再进来,前面returnnfun(n1)这一截得到2,fun(31)得到2,所以最终得到432fun(1)。 fun(1)调用,结果出来就是个1。就是4321。deffun(n):ifn1:return1else:returnnfun(n1)4321fun(4)5。这个递归函数的递归临界点在哪?ifn1:return1 当n1的时候就不会调用自身了。当满足某个条件,不再调用自身,那么这个就被称为递归临界点。 例如改成n1ifn1:return1 这个时候,这个函数的递归临界点在哪? 这个递归临界点就是1。deffun(n):ifn1:递归临界点:当达到递归临界点的时候,就不再调用自身函数的条件return1else:returnnfun(n1)4321fun(4) 任何递归函数,它的原理都是一样的。定义一个递归函数,在递归函数里面它其实就是不断得调用自身,然后设置递归函数的时候,一定不能忘了递归条件。6。斐波那契数列 后面的数都是等于前2个数相加的结果。 斐波那契数列的第一个数值是1,第二个数值也是个1,第三个数等于前两个数相加的结果(那就是2),第四个数等于于前两个数相加的结果(那就是3)。 〔1,1,2,3,5〕 以此类推。