1.生成器代码详解
德夫根() :财富(5) :
j=yield i
是print(j )。
# send:与生成器进行对话
g=gen () )
打印(下一页) g ) )
打印(下一页) g ) )
第一个print(next ) g ) )打印0是生成器生成的元素。 第二个print(j(next(g ) )打印的1也是生成器生成的元素,None是print ) j打印的j。
通过生成器获取元素时,首先生成器进入,调用生成器获取中的值时,它从上往下走,到达j=yield i处,返回yield处的I这个值,返回gen (调用生成器,生成
用这个生成器next(g )取值时,然后从上到下执行代码,到j=yield i的地方。 yield相当于用yield把I放回去。
从生成器返回时,将生成数据。 生成此I,然后打印到第一个打印(下一个) g ) )。
第二个print(next ) g ) ),然后是next ) )中调用生成器时,该生成器将在yield之后继续运行。
用next ()启动生成器时,yield后面没有内容,j接收到的是空的,所以打印j时,打印的是None。
2.生成器的三个方法
#生成器的3种方法:发送关闭德芬(: )
财富(5) :
j=yield i
是print(j )。
# send:与生成器进行对话
g=gen () )
打印(g .发送) 100 ) )
打印(下一页) g ) )
打印(下一页) g ) )
执行后的错误:
生成器发送) )方法从上一个yield结束的位置开始执行。
这里是gen ) )的生成器。 这个生成器还没有生成过数据。 此时生成器在函数的开始处为def gen ) ) :
如果在这里输入send(100 ),则在这里执行,直接执行for i in range(5) :语句,send ) 100 )生成的这个值没有接收到,所以报告错误。
send ) )必须在调用一次后进行调用。 next ) )一样,可以获取生成器的内容。
2.1next()获取生成器里面的内容:
#生成器的3种方法:发送关闭德芬(: )
财富(5) :
j=yield i
是print(j )。
# send:与生成器进行对话
g=gen () )
打印(下一页) g ) )
打印(下一页) g ) )
# #打印(g .发送) 100 ) )
2.2send()在调用了一次next()之后调用,获取生成器里面的内容:
#生成器的3种方法:发送关闭德芬(: )
财富(5) :
j=yield i
是print(j )。
# send:与生成器进行对话
g=gen () )
打印(下一页) g ) )
打印(g .发送) 100 ) )
# #打印(下一步) g ) )
yield只能在函数中使用。 yield关键字在创建生成器时使用。 只要函数使用yield关键字,调用该函数时就不会立即执行该函数。
因为这个函数不是简单的函数,而是生成器。
在函数之外,不能使用yield关键字。
.toutiaoimg.com/origin/pgc-image/eb13e27b129d4dcba30d52f1c317805a?from=pc">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]
以此类推。