Python_迭代器、生成器
迭代器和生成器
迭代器:
只要是能被 for 循环的数据类型,就一定拥有 __iter__ 方法
一个列表执行了 __iter__() 之后的返回值就是一个迭代器
print([].__iter__())
只要含有 __iter__ 方法的都是可迭代的。
通过 next 就可以从迭代器中一个一个的取值
l = [1, 2, 3] iterator = l.__iter__() print(iterator.__next__()) print(iterator.__next__()) 1 2
可迭代协议:
只要含有 __iter__ 方法的都是可迭代的(__iter__ 与 iter() 效果是一样的)
迭代器协议:
内部含有 __next__ 和 __iter__ 方法的就是迭代器
for 循环:
只有是可迭代对象的时候才能用for
当我们遇到一个新的变量,不确定能不能 for 循环的时候,就判断它是否可迭代
迭代器的好处:
从容器类型中一个一个的取值,黑吧所有的值都取到。
节省内存空间
迭代器并不会在内存中再占用一块内存
每次 next 每次给一个值
l = [1, 2, 3, 4, 5] iterator = l.__iter__() while True: print(iterator.__next__())
生成器
生成器函数:
本质上就是我们自己写的函数
只要含有 yield 关键字的函数都是生成器函数
yield 不能和 return 共用且需要写在函数内
生成器函数执行之后会得到一个生成器作为返回值
def generator(): print(1) yield 'a' ret = generator() print(ret) print(ret.__next__())
<generator object generator at 0x0000000000A03AF0>
1
a
send
1、send 获取下一个值的效果和 next 基本一致
2、只是在获取下一个值的时候,给上一个 yield 的位置传递一个数据
3、使用 send 的注意事项
第一次使用生成器的时候,是用 next 获取下一个值
最后一个 yield 不能接受外部的值
def generator(): print(123) content = yield 1 print('=======',content) print(456) yield2 g = generator() ret = g.__next__() print('***',ret) ret = g.send('hello') #send的效果和next一样 print('***',ret)
预激生成器的装饰器
def init(func): #装饰器 def inner(*args,**kwargs): g = func(*args,**kwargs) #g = average() g.__next__() return g return inner @init def average(): sum = 0 count = 0 avg = 0 while True: num = yield avg sum += num # 10 count += 1 # 1 avg = sum/count avg_g = average() #===> inner ret = avg_g.send(10) print(ret) ret = avg_g.send(20) print(ret)