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]吃了 """