迭代器
可以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如 List , Tuple , Dict , Set , Str 等。
一类是generator , 包括生成器和带 yield 的 generator function.
这些可以直接作用于for循环的对象,统称为可迭代对象: Iterable
可以使用isinstance() 判断一个对象是否是Iterable对象:
1 from collections import Iterable 2 3 a = [1,2,3] 4 b = (1,2,3) 5 c = {'name':'Jason'} 6 d = '王振' 7 e = 5.6 8 print(isinstance(a,Iterable)) 9 print(isinstance(b,Iterable)) 10 print(isinstance(c,Iterable)) 11 print(isinstance(d,Iterable)) 12 print(isinstance(e,Iterable))
执行结果
True
True
True
False
可以被next() 函数调用,并不断返回下一个值的对象称为迭代器: Iterator
可以使用 isinstance() 判断一个对象是否是 Iterator 对象
生成器都是Iterator 对象,但List , Dict , Str ,虽然式Iterable ,却不是Iterator。
1 from collections import Iterable,Iterator 2 3 a = (x for x in range(10)) 4 b = [1,2,3] 5 c = {'name':'Jason'} 6 d = '王振' 7 e = 5.6 8 print(isinstance(a,Iterator)) 9 print(isinstance(b,Iterator)) 10 print(isinstance(c,Iterator)) 11 print(isinstance(d,Iterator)) 12 print(isinstance(e,Iterator))
执行结果
True
False
False
False
False
把 List,Dict,Str,等Iterable变成 Iterator 可以使用 iter() 函数。
b = [1,2,3] c = {'name':'Jason'} print(isinstance(iter(b),Iterator)) print(isinstance(iter(c),Iterator))
你可能会问,为什么List,Dict,Str等数据类型不是Iterator?
这是因为Python的 Iterator对象表示的是一个数据流, Iterator对象可以被next()函数调用,并不断返回下一个数据,直到没有数据时抛出StopIteration错误。 可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过 next() 函数实现按需计算下一数据,所以 Interator 的计算是惰性的,只有在需要返回下一个数据时,它才会计算。
Interator甚至可以表示一个无限大的数据流,例如,所有的自然数。而使用 List 是永远不可能存储 所有的自然数的。
总结:
凡是可作用于 for 循环的对象都是 Iterable 类型。
凡是可作用于next() 函数的对象都是 Iterator 类型,它们表示一个惰性计算的序列。
集合数据类型,如 List ,Set ,Dict ,Str等是Iterable 但不是 Iterator ,不过可以通过 iter() 函数获得一个 Iterator对象。
Python的 for 循环本质上就是通过不断调用 next() 函数实现的。例如:
1 for i in [1,2,3,4,5]: 2 pass实际完全等价于:
1 from collections import Iterable,Iterator 2 3 # 首先获得Iterator对象 4 it = iter([1,2,3,4,5]) 5 # 开始循环 6 while True: 7 try: 8 #获得下一个值 9 x = next(it) 10 except StopIteration: 11 # 遇到StopIteration异常,就退出循环 12 break