Python 迭代器与生成器
参考资料:
几分钟听懂迭代器 【哔哩哔哩教程】 (迭代器讲的很好)
Python迭代器与生成器介绍及在Pytorch源码中应用
Python 迭代器深入讲解 |【AsyncIO从入门到放弃#1】 (生成器讲得很好)
Python进阶 | 五分钟带你弄懂迭代器与生成器
迭代器
在python中,如果一个对象有__iter__和__next__方法,那么这个对象就是一个迭代器。
我们也可以调用__iter__函数把可迭代对象变为迭代器。
可迭代对象只有__iter__方法,没有__next__方法。
迭代器既有__iter__方法,也有__next__方法。(这也是迭代器协议所规定的)
在python中,这种前后都有双下划线的方法,既可以用 对象.__iter__() 来调用,也可以直接 iter(对象) 来调用。
对于一个for循环中的迭代,中间过程发生了两件事:
- __iter__函数把可迭代对象变为迭代器;
- 调用迭代器的__next__函数,返回一个元素。
我们自己创建一个简单的迭代器:
class Iterator_test(): def __init__(self, data): self.data = data self.length = len(data) self.index = 0 def __iter__(self): return self def __next__(self): if self.index < self.length: self.index += 1 return self.data[self.index-1] else: raise StopIteration case = Iterator_test([1, 2, 3]) # ========= 用循环的方式获取每一次迭代返回的值 =========== # for num in case: # print(num) # 输出:1 2 3 # ========= 调用iter方法获取每一次迭代返回的值 =========== print(next(case)) # 输出:1 print(next(case)) # 输出:2 print(case.__next__()) # 输出:3 print(next(case)) # 输出:报错,StopIteration的错误
生成器
通常,我们把含有yield的函数称之为生成器函数generator function,把调用生成器函数返回的结果称为生成器generator (或者称为生成器对象)。
生成器是迭代器,不同的是生成器的实现更简洁。
__next__函数是由yield控制的。
return的作用是触发StopIteration异常。
生成器示例:
def count(start=0, step=1, end=8): n = start while n < end: yield n n += step if __name__ == '__main__': c = count(end=5) # c是生成器 # # ===== 用next函数来返回值 # print(next(c)) # 输出 0 # print(next(c)) # 输出 1 # ===== 用for循环来返回值,for循环实际上也是会调用next函数 for i in c: print(i, end=' ') # 输出:0 1 2 3 4
总结一下yield的作用:
- 把函数变为生成器函数;
- 当程序运行到yield语句这里时,yield语句右边的对象作为next()的返回值;
- 返回一个值之后,程序会在yield语句这里暂停,当再次使用next()函数时,程序从该位置继续运行。
class实现的迭代器和yield实现的迭代器比较: