迭代器&生成器
可迭代对象指的是内置有__iter__方法的对象,即obj.__iter__,
包括序列类型如:字符串、列表、元组
无序列类型如:字典、集合、文件
x='he' # print(dir(x)) #查看x可以调用的方法 iter_test=x.__iter__() #把可迭代对象生成迭代器 print(iter_test) print(iter_test.__next__()) #》:h print(iter_test.__next__()) #》:e print(iter_test.__next__()) #>>:报错
迭代器在执行到最后一个后会报错以终止迭代
for 循环
l=[1,2,3] for i in l: #i_l=l.__iter_() i_l.__next__() print(i) for循环做了两件事 1、把可迭代对象转成迭代器,处理每一个元素 2、抓住错误并处理掉
用while模拟for循环
1 l=[1,2,3,4,5] 2 diedai_l=l.__iter__() 3 while True: 4 try: 5 print(diedai_l.__next__()) 6 except StopIteration: 7 break # '迭代完毕,循环终止'
python内置next函数
l=['die','erzi','sunzi','chongsunzi'] iter_l=l.__iter__() print(iter_l.__next__()) #next()---->iter_l.__next__() print(next(iter_l)) #==print(iter_l.__next__()) >>>:die erzi
生成器:可理解为一种数据类型,这种数据类型自动实现迭代器协议,其他数据类型需调用自己内置的__iter__方法
1、生成器函数
yield替代return(但是一个函数中yield可以有多个),yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次从离开它的地方继续执行
1 import time 2 def test(): 3 print('开始生孩子啦。。。。。。') 4 yield '我' #return 5 time.sleep(1) 6 print('开始生儿子啦') 7 yield '儿子出生了' 8 9 time.sleep(2) 10 print('开始生孙子啦') 11 yield '孙子出生了' 12 13 res=test() 14 print(res) 15 print(res.__next__()) #调用一次test() 16 print(res.__next__()) #test() 17 print(res.__next__()) #test()
2、生成器表达式
类似于列表推导,但是生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表
1 ls = [i for i in range(10)] #列表生成式 2 print(ls) 3 >>>:[0,1,2,3,....] 4 5 6 ls_g = (i for i in range(10)) #生成器表达式 7 print(ls_g.__next__()) 8 >>>:0
3、生成器的优点:
提供延迟操作:在需要的时候才产生结果,而不是立即产生结果
yield()和send()
send也可触发生成器,并且能给yield传一个参数
触发生成器三种方式:1、a.__next__() 2、next(a) 3、a.send(参数)
#通过生成器实现协程并行运算 import time def consumer(name): print("%s 准备吃包子啦!" %name) while True: baozi = yield 1 print("包子[%s]来了,被[%s]吃了!" %(baozi,name)) def producer(name): c = consumer('A') #获取一个生成器,此处不会触发函数consumer() c2 = consumer('B') print( c.__next__()) #触发生成器才会执行consumer(),并且遇到yield时中止,等待下一次触发生成器 print(c2.__next__()) print("老子开始准备做包子啦!") for i in range(10): time.sleep(1) print("做了2个包子!") c.send(i) c2.send(i) producer("eric")
注意:
刚获取的生成器是空的,遍历过一遍后也是空的
1 def test(): 2 for i in range(4): 3 yield i 4 t=test() 5 6 t1=(i for i in t) 7 t2=(i for i in t1) 8 print(list(t1)) 9 print(list(t2)) 10 11 >>>:[0, 1, 2, 3] 12 []
三元表达式
三元表达式 name='alex' #name='linhaifeng' res='SB' if name == 'alex' else '帅哥' print(res)
列表解析
l=['鸡蛋%s' %i for i in range(10)] # l1=['鸡蛋%s' %i for i in range(10) if i > 5 ]