Python中迭代对象、迭代器和生成器的比较
###本文从各路资料中摘取了一些进行整理,仅方便自己认识理解,不擅长文笔,见谅###
首先简单看一下概念:
- 迭代对象(iterable):可使用for.. in..进行循环的对象,比如list,tuble,dic,set,string以及迭代器、生成器等都是可迭代的对象。凡是可以返回有一个迭代器的对象都是可迭代的对象。可通过collections包中的isinstance来进行判断,例子如下:
#判断是否为Iterable,可用isinstance >>> from collections import Iterable >>> isinstance({'dede':123},Iterable) True >>> isinstance('hello',Iterable) True >>> isinstance(123,Iterable) False >>> isinstance([1,3],Iterable) True
#实现列表和元素的下表循环 lanage=['python','php','java','c++'] #第一种 for x in range(len(lanage)): print(x,lanage[x]) 第二种 for i ,value in enumerate(lanage): print(i,value) 同一行输出 for i ,value in enumerate(lanage): print(i,value ,end=','
- 迭代器(Iterator):它是一个带状态的对象,他能在你调用
next()方法的时候返回容器中的下一个值,任何实现了__iter__和__next__()(python2中实现next())方法的对象都是迭代器,__iter__返回迭代器自身,__next__返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常,至于它们到底是如何实现的这并不重要。迭代器就是实现了工厂模式的对象,它在你每次询问下一个值的时候给你返回。itertools函数返回的都是迭代器对象。#下面这段代码,通过迭代器的方式书写的一个斐波那契数列,来充分认识__next__和__iter__函数
class Fib: def __init__(self): self.prev = 0 self.curr = 1 def __iter__(self): return self def __next__(self): value = self.curr self.curr += self.prev self.prev = value return value #islice可以使迭代器变为有限序列;cycle可使有限变为无限循环 from itertools import islice >>> f = Fib() >>> list(islice(f, 0, 10)) [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]每次调用
next()方法的时候做两件事:- 为下一次调用
next()方法修改状态 - 为当前这次调用生成返回结果
迭代器就像一个懒加载的工厂,等到有人需要的时候才给它生成值返回,没调用的时候就处于休眠状态等待下一次调用。
- 为下一次调用
我们看一张总概论图:

可得出以下几点:
- iterable>iterator>generator
- 可迭代对象实现了
__iter__方法,该方法返回一个迭代器对象。 - 迭代器持有一个内部状态的字段,用于记录下次迭代返回值,它实现了
__next__和__iter__方法,迭代器不会一次性把所有元素加载到内存,而是需要的时候才生成返回结果。 - 生成器是一种特殊的迭代器,它的返回值不是通过
return而是用yield
最后我们看看生成器yield另一个应用例子:
另一个 yield 的例子来源于文件读取。如果直接对文件对象调用 read() 方法,会导致不可预测的内存占用。好的方法是利用固定长度的缓冲区来不断读取文件内容。通过 yield,我们不再需要编写读文件的迭代类,就可以轻松实现文件读取:
def read_file(fpath): BLOCK_SIZE = 1024 with open(fpath, 'rb') as f: while True: block = f.read(BLOCK_SIZE) if block: yield block else: return
浙公网安备 33010602011771号