1、迭代器

我们已经知道,可以直接作用于for循环的数据类型有如下几种:

    集合数据类型,如:list、tuple、dict、set、str等;

  可以直接作用于for循环的数据结构有如下几种:

    数据结构是generator,包括生成器和带yield的generator function。

  这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。

  可以使用isinstance()判断一个对象是否是Iterable对象

下面是通过isinstance()判断是否是可迭代对象:

 1 >>> from collections import iterable          #这行提示错误注意Iterable  第一个i要大写,不然会出错。
 2 Traceback (most recent call last):
 3   File "<stdin>", line 1, in <module>
 4 ImportError: cannot import name 'iterable'
 5 >>> from collections import Iterable         #Iterable 第一个I大写。
 6 >>> isinstance([],Iterable)
 7 True
 8 >>> isinstance({},Iterable)
 9 True
10 >>> isinstance("abc",Iterable)
11 True
12 >>> isinstance((x for x in range(10)),Iterable)
13 True
14 >>> isinstance(100,Iterable)
15 False
16 >>>

命令截图如下:

 

 生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误,

表示无法继续返回下一个值了。

 可以被next()函数调用并不断返回下一个值的对象称为迭代器:Interator。

下面是通过isinstance()判断是否是可迭代对象:

 1 >>> from collections import Iterator
 2 >>> isinstance((x for x in range(5)),Iterator)
 3 True
 4 >>> isinstance([],Iterator)
 5 False
 6 >>> isinstance({},Iterator)
 7 False
 8 >>> isinstance("abc",Iterator)
 9 False
10 >>>

命令截图:

结论:

  生成器一定是迭代器(因为有next()方法),而迭代器不一定是生成器(Iterator)。

  list、dict、str虽然是可迭代对象(Iterable),但不是迭代器(Iterator)   通过iter()则可以变为可迭代对象

       将list、dict、str等Iterable变为Iterator可以使用iter()函数。

1 >>> from collections import Iterator
2 >>> isinstance(iter([]),Iterator)
3 True
4 >>> isinstance(iter({}),Iterator)
5 True
6 >>> isinstance(iter("abc"),Iterator)
7 True
8 >>>

命令截图:

为什么list、dict、str等数据类型不是Iterator?

  因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,知道没有数据时抛出StopIteration错误,可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时才会计算。

 

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不能存储全体自然数的。

小结:

  凡是可作用于for循环的对象都是Iterable。

  凡是可以作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列。

  集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

Python的for循环本质上就是通过不断调用next()函数实现的。例如:

for x in range(5):
    print(x)

返回结果:

 实际上等价于:

 1 # 首先获取Iterator对象
 2 it = iter([0,1,2,3,4])
 3 # 循环
 4 while True:
 5     try:
 6         # 在循环中获取下一个值。
 7         x = it.__next__()
 8         print(x)
 9     except StopIteration:
10         # 遇到StopIteration错误就直接退出。
11         break

文件:

Python3.0上文件的调用f.readline()就是迭代器。已经看不到痕迹了。

Python2.7上 文件有next方法,但是不能直接用,需要用f.xreadline()转换一下才可以用。

只要是for line in f:就是使用迭代器的方法调用。

 posted on 2018-08-05 21:27  二十二a  阅读(186)  评论(0编辑  收藏  举报