Python3基础-生成器

创建生成器对象的两种方式

创建一个生成器对象有两种方式
1、调用带yield关键字的函数:函数体包含了 yield关键字,再调用函数,并不会执行函数体代码。得到的返回值即生成器对象
2、生成器表达式,与列表生成式的语法格式相同,只需要将[]转换成()
生成器内置有__iter__和__next__方法,所以生成器本身就是一个迭代器

生成器函数

def wrapper(dict):
    for key,item in dict.items():
        yield  key,item

dict = {'name': 'susu', 'paaswd': '123456','level':'优秀'}
dict_wra=wrapper(dict)
print(dict_wra.__iter__())
print(dict_wra.__next__()) #调用next()函数执行直到遇到yield则停止,将yield后的值返回,并在当前位置挂起函数
print(next(dict_wra))  #再次调用next(),函数从上次暂停的位置继续执行,直到重新遇到yield
print(next(dict_wra))  #继续...
print(next(dict_wra))  #没有遇到yield则无值返回,即取值完毕后抛出异常StopIteration,结束迭代

"""
执行结果
<generator object wrapper at 0x00DE2270> ('name', 'susu') ('paaswd', '123456') ('level', '优秀') StopIteration
"""
def test():
    print('start------1')
    yield  1
    print('start------2')
    yield  2
    print('start------3')
    yield  3

test1=test()
print(next(test1))
"""
执行结果
start------1
1
"""
def test():
    print('start------1')
    yield  1
    print('start------2')
    yield  2
    print('start------3')
    yield  3

test1=test()
print(next(test1))
print(next(test1))
"""
执行结果
start------1
1
start------2
2
"""

 

yield 与 return的区别

1、return 函数一旦遇到return就结束了
2、yield 可以用于返回值,但是yield可以保存函数的运行状态挂起函数,用来返回多次值

三元表达式

res= 条件成立时返回的值 if 条件      else 条件不成立时返回的值

#比大小
x = 10
y = 20
res = x if x>y else y #三元表达式
print(res)  #输出 20

列表生成式

#场景
list=[]
for i in range(10):
    list.append(i)
print(list)
#列表生成式 返回的是一个列表
list=[i for i in range(10)]
print(list)

list=[i for i in range(10) if i > 4] #三元
print(list)

#list=[i for i in range(10) if i > 5 else '122'] #报错
#print(list)
"""
执行结果
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[5, 6, 7, 8, 9]

生成器表达式

list=(i for i in range(10) if i > 4) #三元
print(list) #<generator object <genexpr> at 0x031122F0>
print(next(list))  #输出的 5
print(next(list))  #输出的 6
print(next(list))   #输出的 7
print(next(list))    #输出的 8
print(next(list))    #输出的 9
print(next(list))   #异常 StopIteration
#列表生成式与生成器表达式
1、列表生成式 返回的是一个列表;生成器表达式返回的是一个生成器对象
2、对比列表生成式,生成器表达式的优点是:节省内存【一次只产生一个值在内存中】
3、列表生成式语法格式是用[]括起来
4、生成器表达式语法格式是用()括起来

生成器send()函数

def Gene():  # 生成器函数
    print("ok")
    x = 100
    print('x=====:',x)
    first = yield 50  # 这里就是send函数的关键  send(30)所传递的值其实就是给 =号左边的左值赋值

    print('first=====:',first)

    second = yield x  # 这里试第二个断点
    print('second=====:',second)

    z ='third'
    third = yield z
    print('third=====:',third)


inst = Gene()  # 创建生成器对象
output1 = inst.send(None)  # 启动生成器,运行到第一个yield
print(output1)  # 这边的output1获得的是yield的返回值 50
output2 = inst.send(30)
print(output2)
output3 = inst.send(None)
"""
执行结果
ok
x=====: 100
50
first=====: 30
100
second=====: None
"""
注意:每次的send(params)都会运行到yield语句,但赋值不会执行,只会有返回值。赋值在下一次send(params)时将xx赋值为params 
#生产者和消费者
def consumer(name):
    print("我是[%s],准备开始吃了"%name)
    while True:
        baozi = yield
        print("%s,很开心的把[%s]吃了"%(name,baozi))

def producer():
    c1 = consumer('suus')
    c2 = consumer('suus1')
    c1.__next__()
    c2.__next__()
    for i in range(1,10):
        time.sleep(1)
        c1.send("油条 %s" %i)
        c2.send("油条 %s" %i)
producer()

"""
执行结果
我是[suus],准备开始吃了
我是[suus1],准备开始吃了
suus,很开心的把[油条 1]吃了
suus1,很开心的把[油条 1]吃了
suus,很开心的把[油条 2]吃了
suus1,很开心的把[油条 2]吃了
suus,很开心的把[油条 3]吃了
suus1,很开心的把[油条 3]吃了
suus,很开心的把[油条 4]吃了
suus1,很开心的把[油条 4]吃了
suus,很开心的把[油条 5]吃了
suus1,很开心的把[油条 5]吃了
suus,很开心的把[油条 6]吃了
suus1,很开心的把[油条 6]吃了
suus,很开心的把[油条 7]吃了
suus1,很开心的把[油条 7]吃了
suus,很开心的把[油条 8]吃了
suus1,很开心的把[油条 8]吃了
suus,很开心的把[油条 9]吃了
suus1,很开心的把[油条 9]吃了
"""







posted @ 2019-10-21 19:28  槑槑DE  阅读(210)  评论(0编辑  收藏  举报