<30>python学习笔记——生成器

列表生成式(使用的是中括号)

[ 函数或运算方法  for  元素  in   可迭代对象 ]

列表生成式先将列表准备好,然后依次将元素带入函数或运算方法中进行操作,并依次返回值

所以可以使用列表切片的方式操作数据。如 :c [100]是可以的

示例1:

[i*2 for i in range(10)]
Out[3]: 
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
示例2:

def add(i):
    i *=10
    print(i)

resuls = [add(i) for i in range(10)]
print(resuls)

生成器(使用的是小括号)

( 函数或运算方法  for  元素   in   可迭代对象)

生成器准备了一个算法,只有在调用的时候才生成数据,然后依次将元素带入函数或运算方法中进行操作,并依次返回值

生成器没法用列表切片的方式取值 如:c [100]  是错误的。

生成器只能记住当前位置,只能用 __next__()方法 获取下一个数据。而且不能返回取之前的数据。

##通过函数做了一个生成器
def fib(max):
    n,a,b = 0,0,1
    while n< max:
        ##要想返回什么,就把 yield 放到那个位置。yield是保存了函数的中断状态,下一次还回到这个位置
        yield b ##通过yield 在单线程下可以实现并发效果。
        a,b = b,a+b
        n +=1

# print(fib(100))
##变成生成器的函数。不需要等待函数全部生成,可以暂时中断函数运行,需要的时候再调用

f = fib(100)
print(f.__next__())
print('----------我是插进来运行的东西--------')
print(f.__next__())
print('----------我又插进来一下--------')
print(f.__next__())
print(f.__next__())

用函数实现生成器

还可以通过yield实现在单线程下的情况下实现并发运算的效果

代码1:说明send()对yield的作用

def consumer(name):
    print('%s 准备吃包子' %name)
    while True:
        ##yield保存当前状态,
        baozi = yield  ##走到这就返回,下面的语句不执行
        print('包子[%s]被 [%s] 吃了'% (baozi,name))

c = consumer('dralon')
c.__next__()##取值
b1 = '韭菜包子'
c.send(b1)##send把b1的值传递进函数,被yield接收到,并赋值给了'baozi'
##send 调用yield,同时给yield传值。
##__next__只是调用yield
c.__next__()

##运行结果:
# dralon 准备吃包子
# 包子[韭菜包子]被 [dralon] 吃了 (send 调用yield,同时给yield传值。)
# 包子[None]被 [dralon] 吃了  (__next__只是调用yield)
代码2,实现单线程下并发运算的效果
import time

def consumer(name):
    print('%s 准备吃包子' %name)
    while True:
        ##yield保存当前状态,
        baozi = yield  ##走到这就返回,下面的语句不执行
        print('包子[%s]被 [%s] 吃了'% (baozi,name))

def producer(name):
    c1 = consumer('A----') ##c1开始调用consumer函数
    c2 = consumer('----B') ##c2开始调用consumer函数
    c1.__next__() ##c1取第一次运行,会在yield的位置停下来
    c2.__next__()##c1取第一次运行,会在yield的位置停下来

    print('我开始做包子啦!')
    for i in range(3):
        time.sleep(1)
        print('做了一个包子,分两半')
        c1.send(i)  ##c1调用yield,并将值传给了yield,所以consumer函数有继续运行下去
        c2.send(i)  ##c2调用yield,并将值传给了yield,所以consumer函数有继续运行下去

producer('dralon')

运行结果:

A---- 准备吃包子
----B 准备吃包子
我开始做包子啦!
做了一个包子,分两半
包子[0]被 [A----] 吃了
包子[0]被 [----B] 吃了
做了一个包子,分两半
包子[1]被 [A----] 吃了
包子[1]被 [----B] 吃了
做了一个包子,分两半
包子[2]被 [A----] 吃了
包子[2]被 [----B] 吃了



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值