迭代器和生成器
Iterator(迭代器)
迭代器是访问集合元素的一种方式,是一个可以记住当前访问位置的对象
-
将对象转成迭代器使用iter()
a = [1,2,3] iter(a) next(a) >>> 1 -
迭代器可以使用next()进行遍历,当全部遍历完之后,就会抛出StopIteration异常
-
定义可迭代的类,两个关键要素:__iter__和__next__,通常使用的for...in...就是使用的这两个要素
class Reverse: def __init__(self,data): self.data = data self.index = len(data) def __iter__(self): return self def __next__(self): if self.index == 0: raise StopIteration self.index = self.inedex -1 return self.data[self.index] rev = Reverse([1,2,3]) next(rev) >>> 3 for i in rev: print(i) """ 2 1 """ -
比起列表(list)来说,迭代器最大的优势就是延迟计算,按需使用,从而提高开发体验和运行效率,也能节省内存,以至于在Python 3中map,filter等操作返回的不再是列表而是迭代器
Generator(生成器)
使用了yield的函数是生成器
生成器是一个返回迭代器的函数,同时它就是迭代器
每次调用next()在生成器上时,都会从之前访问的位置继续开始
这个特点常用于流水线和异步,比如:
播放一段视频,你突然有事走开,需要暂停视频,等你忙完回来,在从暂停位置开始看起,而不是从视频的开头开始,重头看起
创建生成器
-
和创建列表类似,但是不用中括号
[]而是用括号()gen = (x for i in range(10)) # ()生成器,[]列表,{}集合或者键值对 # 遍历 while True: try: print(next(gen)) except StopIteration: break ------------------------------ for i in gen: print(i)
创建生成器函数
# 函数有了yield之后,函数名+()就变成了生成器
# return在生成器中代表生成器的中止,直接报错
# next的作用是唤醒并继续执行
# send的作用是唤醒并继续执行,发送一个信息到生成器内部
'''生成器'''
def coro():
say_hello = yield 'hello' # 第一次返回的值是'hello'但是没有赋值给变量say_hello
# 第二次将发送的值传给了变量say_hello,say_hello='world',继续往下执行
yield say_hello
c = coro() # 生成协程,生成协程后的第一步是c.send(None)或者next(c)
type(c)
print(next(c)) # 或者使用send(None),next(c)=c.send(None)
print(c.send('world'))

浙公网安备 33010602011771号