WELCOME

不积跬步,无以至千里;不积小流,无以成江海。

Python生成器

1.生成器

  通过列表生成式(列表推导式),|我们可以直接创建一个列表。但是,受到内存限制,列表容量中定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们
仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就
不必创建完整的list,从而节省大量的空间在Python中,这种一边循环一边计算的机制,称为生成器: generator

 

2.通过列表推导式得到生成器

1 newlist = [x * 3 for x in range(10)] 2 print(newlist) 3 4 # 得到生成器 5 g = (x * 3 for x in range(10)) 6 print(type(g)) # >> <class 'generator'> 7 print(g) # >> <generator object <genexpr> at 0x000001FA1AF01548> 8 # 方式一:通过调用__next__()方式得到元素 9 print(g.__next__()) # >> 0 10 print(g.__next__()) # >> 3 11 print(g.__next__()) # >> 6 12 print(g.__next__()) # >> 9 13 14 # 方式二:next() 系统内置的函数:next(生成器对象) 每调用一次则会产生一个元素 15 print(next(g)) # >> 12 16 print(next(g)) # >> 15 17 print(next(g)) # >> 12 18 print(next(g)) # >> 15 19 # StopIteration 生成器本来可以产生10个,得到了10个,再调用next(g),则会抛出异常!

 

  通过循环来调用生成器,并加上产生异常的处理:

 

1 g = (x * 3 for x in range(10)) 2 while True: 3 try: 4 e = next(g) 5 print(e) 6 except: 7 print('元素产生完毕,没有更多的元素了') 8 break

 

3.借助函数得到生成器

步骤: 1.定义一个函数,函数中使用yield关键字 2.调用函数,接收调用的结构 3.得到的结果就是一个生成器:<generator object func at 0x0000021AEB0B13C8> 4.借助于next(),__next__()得到元素部分 简单地讲,yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数, Python 解释器会将其视为一个generator,

 

1 # 函数中出现yield关键字,说明函数就不是一个函数,变成了一个生成器 2 def func(): 3 n = 0 4 while True: 5 n += 1 6 yield n # --> (return + 暂停)的作用 7 8 9 g = func() 10 print(g) # >> <generator object func at 0x0000021AEB0B13C8> 11 print(next(g)) # >> 1 12 print(g.__next__()) # >>2 13 14 ''' 15 yield相当于return+暂定的作用,当n=n+1=1时。返回1,然后暂停在这儿,打印1之后,继续从yield下面开始执行 16 '''

 

·  斐波那契数列:

1 # 斐波那契数列 2 3 def fib(length): 4 a, b = 0, 1 5 n = 0 6 while n < length: 7 # print(b) 8 yield b # return + 暂停 9 a, b = b, a + b 10 n += 1 11 return '没有更多元素了!!!' # return就是在得到StopIteration,即错误提示信息 12 13 14 g = fib(8) 15 print(next(g)) # >> 1 16 print(next(g)) # >> 1 17 print(next(g)) # >> 2 18 print(next(g)) # >> 3 19 print(next(g)) # >> 5 20 print(next(g)) # >> 8 21 print(next(g)) # >> 13 22 print(next(g)) # >> 21 23 print(next(g)) # >> StopIteration: 没有更多元素了!!!
首先a,b=0,1,0<8,yield b:return b的值,然后暂定,直接跳到print(next(g))
然后跳到下一个print(next(g)),再到a,b=b,a+b这一步,n +=1,说明产生一个元素,
n=1<8,成立,则yield b,即扔出结果1,再又从a,b=b,a+b开始执行。

 

 

 

 

4.send()函数

生成器方法:
__next__():获取下一个元素 send(value):向每次生成器调用中传值,第一次调用必须传一个空值send(None)
send()的作用是使xx赋值为发送的值(send的参数),然后让生成器执行到下个yield.. 使用send(params)需要区分情况。注意:如果生成器未启动,则必须在使用send()前必须要启动生成器,而启动的方法可以是generator.next()或是generator.send(None) 执行到第一个yield处.之后就可以使用send(params)不断传入值了。如果是已启动,则send(params)的作用就是给xx赋值为发送的值(send的参数),然后让生成器执行到下个yield.. 为什么需要send(None),也很好理解,因为 生成器还没有走到第一个yield语句,如果我们发生一个真实的值,这时是没有人去接收它的。一旦生成器启动了,就对象接受(即=号左边 的左值xx接受了),之后就可以使用send(params)不断传入值了

 

1 def gen(): 2 i = 0 3 while i < 5: 4 temp = yield i # return 0 ,暂停 5 print('temp:', temp) 6 for x in range(temp): 7 print('----------->',x) 8 print('***************') 9 i += 1 10 return '没有更多数据了' 11 12 13 g = gen() 14 # print(next(g)) 15 # print(next(g)) 16 # print(next(g)) 17 18 print(g.send(None)) 19 n1 = g.send(3) 20 print('n1:', n1) 21 n2 = g.send(5) 22 print('n2:', n2)

0
temp: 3
-----------> 0
-----------> 1
-----------> 2
***************
n1: 1
temp: 5
-----------> 0
-----------> 1
-----------> 2
-----------> 3
-----------> 4
***************
n2: 2

 

5.生成器应用(协程)

1 def task1(n): 2 for i in range(n): 3 print('正在搬第{}块砖'.format(i)) 4 yield None 5 6 7 def task2(n): 8 for i in range(n): 9 print('正在听第{}首歌'.format(i)) 10 yield None 11 12 13 g1 = task1(5) 14 g2 = task2(5) 15 16 while True: 17 try: 18 next(g1) 19 next(g2) 20 except: 21 break 22 23 ''' 24 正在搬第0块砖 25 正在听第0首歌 26 正在搬第1块砖 27 正在听第1首歌 28 正在搬第2块砖 29 正在听第2首歌 30 正在搬第3块砖 31 正在听第3首歌 32 正在搬第4块砖 33 正在听第4首歌 34 '''

 


__EOF__

本文作者Ambitious
本文链接https://www.cnblogs.com/ambitiousPlus/p/16060683.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Ambitious~  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示