首页 > Python基础教程 >
-
python基础教程之迭代器与生成器
1. 迭代器
1. 定义: 内部含有__next__和__iter__ 方法就是迭代器.
2. 可迭代协议: 可以被for循环的都是可迭代的,内部都有__iter__方法.
3. 目前所学可迭代对象有: 字符串,列表,字典,元组,集合,range, f = read()
print(dir(list)) # dir() : 查看对应的方法,如果有__iter__表示为可迭代对象
4. 可迭代对象.__iter__就可以获得一个迭代器
result = dir(list) iterator = list.__iter__() # 获得一个迭代器 print(iterator)
5. 迭代器中的__next__方法可以一个一个的获取值
list = [1, 2, 3] iterator = list.__iter__() res = iterator.__next__() print(res) res = iterator.__next__() print(res)
6. for循环的本质: iterator = 可迭代对象.__iter__()
iterator.__next__()
for i in list1.__iter__(): print(i)
7. 迭代器的好处:
a. 从容器中取值,会把所有的值都取到
b. 可以节省内存空间,随着循环每生成一个数,__next__方法每次给出一个数
2.生成器
1. 生成器的本质: 自己写的迭代器
2. 生成器函数: 执行后会得到一个生成器作为返回值
a. 关键字: 只要含有yield关键字的函数都是生成器函数,yield不能和return共用且需要写在函数内部
b. yield和return的区别: yield和return都能返回后面的值,return执行后结束当前函数,yield也会返回值,但函数不结束
3. 生成器案例:使用生成器创建十万个娃哈哈,先取50瓶,喝完再取两瓶,喝完再取50瓶
def wahaha(): for i in range(100000): yield f'第{i}瓶娃哈哈' g = wahaha() count = 0 for i in g: print(i) count += 1 if count > 50: break print(g.__next__()) print(g.__next__()) for i in g: print(i) count += 1 if count > 100: break
4. 生成器函数的特点:
a. 调用函数之后函数不执行,返回一个生成器
b. 每次调用__next__方法的时候会取到一个值,直到取完最后一个,再执行next的时候会报错
5. 从生成器中取值的方法:
a. __next__方法
b. for 循环
c. 数据类型强制转换,占用内存
6. send()方法 : 获取下一个值的效果和next基本一致
a. 特点 : 只是在获取下一个值的时候,给上一个yield的地方传递一个数据
b. 注意事项 : 第一次使用生成器的时候,使用next获取下一个值
最后一个yield不能接收外部的值
def generator(): print(123) content = yield 1 print('=========', content) print(456) yield 2 g = generator() print(g) result = g.__next__() print(result) result = g.send('hello') print(result)
7. send案例 : 计算移动平均值
def avgerage(): sum = 0 count = 0 avg = 0 while True: num = yield avg sum += num count += 1 avg = sum/count avg_g = avgerage() avg_g.__next__() # 激活生成器 result = avg_g.send(10) result = avg_g.send(20) result = avg_g.send(30) result = avg_g.send(40) print(result)
8. 生成器结合装饰器: 预激生成器的装饰器
def init(func): def inner(*args, **kwargs): g = func(*args, **kwargs) g.__next__() # 在装饰器内部激活 return g return inner @init def avgerage(): sum = 0 count = 0 avg = 0 while True: num = yield avg sum += num count += 1 avg = sum/count avg_g = avgerage() result = avg_g.send(10) result = avg_g.send(20) result = avg_g.send(30) result = avg_g.send(40) print(result)
9. yield from 将容器内的数据挨个遍历
def generator(): a = '12345' b = 'abcde' yield from a yield from b g = generator() for i in g: print(i)
10. 生成器表达式
generator = (i ** 2 for i in range(10)) print(generator) for i in generator: print(i)