一、迭代器
1、迭代器概念
1.1迭代器协议:是指对象必须提供一个next方法,执行该方法要么范湖迭代中的下一项,要么就引起一个stopIteration的异常,以终止迭代(只能往后走不能往前 退)
1.2 可迭代对象:实现了迭代器协议的对象。迭代:通俗讲就是一个更新换代的过程
1.3协议是一种约定,可迭代对象实现了迭代器协议,Python中的内部工具(如for循环,min函数,sum等)使用迭代器协议访问对象。
2、for循环机制,是基于迭代器协议工作的
2.1 for循环可遍历的数据类型:
1)有序类型:字符串、列表和元组
2)无序类型:字典、集合和文件
2.2 for循环工作原理
1)先把要遍历的数据累心调用内部_ilter_方法,转换为可迭代的对象
2)帮助查找对吼的异常后,终止
总结:For循环就是基于迭代器协议提供一个统一的可以遍历所有对象的方法
3、样例
l=[1,3,2] for i in l: #先把列表l变成一个可可迭代对象,使其遵循迭代协议,然后for循环才能按照迭代器协议去循环遍历 print(i) iter_l=l.__iter__() print(iter_l.__next__())
#方式二:内置函数next,next方法就是在调用迭代器iter_l.__next__()本身这个方法
l=[1,3,2]
iter_l=l.__iter__()
print(next(iter_l))
dic={"a":1,"b":22} iter_d=dic.__iter__() print(iter_d.__next__()) print(iter_d.__next__()) #_next_()方法执行的结果就是key值 #方式二: for i in dic: print(i)
二、生成器
1)自动实现了迭代器协议,本身就是可迭代对象,延迟计算节省内存
2)列表解析的[ ]换成( ) 得到的就是生成器表达式
3)列表解析和生成器表达式都是一种便利的编程方式,生成器表达式相对之下更加节省内存
4)Python中for循环时一种基于迭代器协议完成作业的
1、三元表达式&列表解析
name="CC" res="肖战" if name=="CC" else "青" #三元表达式 print(res) #方式二 l=["鸡蛋%s" %i for i in range(10) if i>5] #列表解析 print(l) #结果:['鸡蛋6', '鸡蛋7', '鸡蛋8', '鸡蛋9']
2、生成器表达式
l=("鸡蛋%s" %i for i in range(10) if i>5) print(l) print(l.__next__()) print(next(l)) #结果: <generator object <genexpr> at 0x00000243BFCD9258> 鸡蛋6 鸡蛋7
3、生成器函数
生成器好处:1)yield相当于return,用来作为返回值
2)保留函数运行状态,从上一次next终止位置继续运行
3.1样例
import time def test(): time.sleep(3) yield 1 #每一yield相当于一个return返回 yield 2 print("开始啦") yield 3 res=test()#拿到生成器 print(res) #生成器对象 print(res.__next__())#运行生成器yield1 print(res.__next__())#运行生成器yield2 print(res.__next__())#运行生成器yield3
import time def test(): print("一开始啦") yield "我" time.sleep(3) print("二开始啦") yield "她" time.sleep(3) print("三开始啦") yield "他" res=test() print(res) #生成器对象 print(res.__next__())#运行生成器yield我 print(res.__next__())#运行生成器yield她 print(res.__next__())#运行生成器yield他
def prduct_baozi(): for i in range(100): print("开始蒸包子啦") yield "蒸好了一屉%s"%i print("开始卖包子") pro1=prduct_baozi() baozi=pro1.__next__() baozi=pro1.__next__() baozi=pro1.__next__() baozi=pro1.__next__()
3.2send函数停留位置,send的值就是给停留位置赋值的
def test(): print("开始啦") first=yield print("第一次",first) yield 2 print("第二次") t=test() res=t.__next__() print(res) res=t.send("函数停留在first那个位置,我就是给first赋值的") print(res)
3.2 生产者消费者模型(单线程并发)
#过程一:两个人吃包子
import time
def custmer(name):
print("我是[%s],我准备吃包子了"%name)
while True :
baozi=yield
time.sleep(1)
print("%s 很开心的把[%s]吃掉了" %(name,baozi))
c1=custmer("CC")
c2 = custmer("娜娜")
c1.__next__()
c2.__next__()
c1.send("包子" )
c2.send("包子" )
#过程二:运用函数自动做包子
import time
def custmer(name):
print("我是[%s],我准备吃包子了"%name)
while True :
baozi=yield
time.sleep(1)
print("%s 很开心的把[%s]吃掉了" %(name,baozi))
def productor():
c1=custmer("CC")
c2 = custmer("娜娜")
c1.__next__()
c2.__next__()
c1.send("包子" )
c2.send("包子" )
productor()
#过程三:制作多个包子for循环
import time def custmer(name): print("我是[%s],我准备吃包子了"%name) while True : baozi=yield time.sleep(1) print("%s 很开心的把[%s]吃掉了" %(name,baozi)) def productor(): c1=custmer("CC") c2 = custmer("娜娜") c1.__next__() c2.__next__() for i in range(10): time.sleep(1) c1.send("包子%s" %i) c2.send("包子%s" % i) productor()