结论
1)可迭代对象包含迭代器。
2)如果一个对象拥有__iter__方法,其是可迭代对象;如果一个对象拥有next方法,其是迭代器。
3)生成器是一种特殊的迭代器,生成器自动实现了“迭代器协议”(即__iter__和next方法)
优点
对于数据量大的元素,减少内存空间
相关概念
Iterable:可迭代对象
Iterator:迭代器
1、可迭代对象
只有iter() 方法,例如
一类是集合数据类型,如list、tuple、dict、set、str等; 一类是generator,包括生成器和带yield的generator function
from collections import Iterable
from collections import Iterator >>> isinstance([],Iterable) True >>> isinstance(('abc','awe'),Iterator) #可以使用dir([])查看到里面只有iter()方法 False >>> isinstance({},Iterable) True >>> isinstance(123,Iterable) False
2、迭代器
迭代器具有iter() 和 next()方法的对象.
iter()返回迭代器本身
next()返回容器的下一个元素,在结尾处引发StopInteration异常
将一个可迭代对象转换为迭代器:
it = iter(iterable) next(it) # 获取下一个迭代器中的下一个值
你可能会问,为什么list、dict、str等数据类型不是Iterator?
这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。
可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
3、生成器
3.1生成器表达式:
列表推导式: sum([i+1 for i in range(1000000000)]) 前面是一个表达式,表示结果,后面跟一个for加一个可迭代的对象,再后面还可以跟# 一个if else 语句进行判断 生成器表达式: sum((i+1 for i in range(1000000000)))
3.2生成器函数,带yield的函数:
生成器是一个特殊的函数,可以被用作控制循环的迭代行为,python中生成器是迭代器的一种,使用yield代替return返回,每次调用yield会暂停,而可以使用next()函数和send()函数恢复生成器.
def myList(num): # 定义生成器 now = 0 # 当前迭代值,初始为0 while now < num: val = (yield now) # 返回当前迭代值,并接受可能的send发送值;yield在下面会解释 now = now + 1 if val is None else val # val为None,迭代值自增1,否则重新设定当前迭代值为val