一:迭代器
1.迭代器协议:是指迭代器对象必须提供一个next()方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常来中止迭代(如下一项不存在的时候),只能向后走而不能向前退。
2.可迭代对象:满足迭代器协议的对象(python中通过对象内部定义一个__iter__()方法来实现迭代器对象)
列表,字符串,元组等并不是迭代器对象,只是在使用for循环,max等工具时调用了他们内部的__iter__()方法返回了一个可迭代对象来进行迭代的操作(for循环会自动捕捉StopIteration异常来中止迭代)。
x=[1,2,3,4,5,6]iter_test=x.__iter__()print(iter_test)print(iter_test.__next__())print(iter_test.__next__())print(iter_test.__next__())print(iter_test.__next__())print(iter_test.__next__())print(iter_test.__next__()) #利用python自带的next()内置方法也可以,效果等同于__next__() print(next(iter_test)) 结果:1 2 3 4 5 6
二: 生成器
1.生成器自动实现了可迭代协议,可以理解为生成器就是可迭代对象。
2.生成器函数是在函数中使用yield时返回的时生成器对象。
def test(): print("aa") print("bb") yield [1,2]#当运行至此时,函数挂起,当再次运行next方法时,函数会从当前位置继续运行。 print("dsa") yield 2 print("fsd") yield 3res=test()print(res.__next__())print(res.__next__())print(res.__next__())# 输出:aa# bb# [1, 2]# dsa# 2# fsd# 3#三元运算a=2res=1 if a==2 else 3print(res)#列表解析l=[i for i in range(10)]#三元运算和列表解析结合l=[i for i in range(10) if i>5]#l=[i for i in range(10) if i>5 else 3]此时不可以,没有四元表达式#把列表解析的[]换成(),就会得到生成器表达式l=(i for i in range(10))l.__next__()sum(i for i in range(10))#利用生成器表达式可减少内存占用
3.发蛋案例感受生成器函数好处:
# #缺点1:占空间大# #缺点2:效率低# def xiadan():# ret=[]# for i in range(100):# ret.append(i)# return ret# print(xiadan())#生成器函数,来一个给一个def xiadan(): for i in range(100): yield ires=xiadan()print(res.__next__())print(res.__next__())
4.其他例子(注意,生成器只能被迭代一次):
#占用内存大sum([i for i in range(10000)])#占很少内存sum(i for i in range(10000))#假设文件内容为:{ 'name':'weq','population':20}{ 'name':'ewqe','population':5}{ 'name':'fsd','population':6}def get_pop(): with open('b.txt','r') as f: for i in f: yield ig=get_pop()s1=eval(g.__next__())#将字符串转换为字典print(s1['population'])#统计总人口sum(eval(i)['population'] for i in g)