直接作用于for
循环的对象: 称为可迭代对象:Iterable
可以使用
isinstance()
判断一个对象是否是Iterable
对象:
from collections import Iterable
isinstance('ddd',Iterable)
生成器——不但可以作用于for
循环,还可以被next()
函数不断调用并返回下一个值,直到最后抛出StopIteration
错误表示无法继续返回下一个值。
迭代器——可以被next()
函数调用并不断返回下一个值的对象称为迭代器:Iterator
。(包括generator)
可以使用isinstance()
判断一个对象是否是Iterator
对象:
from collections import Iterator
isinstance((x*x for x in range(1,5),Iterator)
so, 生成器都是Iterator
对象,但list
、dict
、str
虽然是Iterable(可迭代对象)
,却不是Iterator(迭代器)
。(因为Python的Iterator
对象表示的是一个数据流,可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()
函数实现按需计算下一个数据,所以Iterator
的计算是惰性的,只有在需要返回下一个数据时它才会计算。)
把list
、dict
、str
等Iterable
变成Iterator
可以使用iter()
函数:
前面加个iter()
eg: isinstance(iter('dsfdsf'),Iterator)
Iterator
甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
小结
凡是可作用于for
循环的对象都是Iterable
类型;
凡是可作用于next()
函数的对象都是Iterator
类型,它们表示一个惰性计算的序列;
集合数据类型如list
、dict
、str
等是Iterable
但不是Iterator
,不过可以通过iter()
函数获得一个Iterator
对象。
Python的for
循环本质上就是通过不断调用next()
函数实现的,例如:
for x in [1, 2, 3, 4, 5]: #[1,2,3,4,5]可作用于for循环,是Iterable类型
pass
实际上完全等价于:
# 首先获得Iterator对象:
it = iter([1, 2, 3, 4, 5]) #加上iter()函数,使[1,2,3,4,5]变成Iterator类型,下面才能作用于next()函数对象。
# 循环:
while True:
try:
# 获得下一个值:
x = next(it)
except StopIteration:
# 遇到StopIteration就退出循环
break
itetator:迭代器,惰性序列,能next();包含generator生成器,还有iter(iterable对象),比如iter(list),iter(dict),iter(str).
generator 必然是 Iterator,所有 Iterable 对象均可使用 iter() 函数变为 Iterator。
数组(Iterable类型但不是Iterator)与生成器(即是Iterable也是Iterator):
迭代器像一条未动工的马路,当我要在马路过的时候,我走多远修多远,边走边修的类型,理论上只要钱到位,马路可以一直修;
而数组则是一条修好的马路,不管走多远,能不能走,反正就这么长,是有长度限制的;突然有一天天降横财,爸爸我也想让马路可以无限修,然后上帝给了你一个叫做iter的函数,让你变的和土豪一样了,马路也可以边走边修了.
总结:迭代器是惰性的,用多少生产多少;可迭代对象是一下全部返回,不管用到用不到.
迭代对象是指可以被for循环遍历的一组对象,而迭代器则不单单是可以被迭代,而且可以是根据next()返回的,需要根据算法得到下一个值的!iter()是将Iterable转换为Iterator!