Day11 python高级特性-- 迭代器 Iterator

时间:2022-10-04 22:38:08
直接可以作用于for循环的数据类型有以下几种:
   •  集合数据类型:
        list、tuple、dict、set、str
   •  Generator:
        生成器 和 带 yield 的generator function.
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
可以通过isinstance() 判断一个对象是否是Iterable对象:
        >>> from collections import Iterable
        >>> isinstance('abc', Iterable)
        True
        >>> isinstance([], Iterable)
        True
        >>> isinstance({}, Iterable)
        True
        >>> isinstance((), Iterable)
        True
        >>> isinstance((123), Iterable)
        False
        >>> isinstance((x*x for x in range(1,5)), Iterable)
        True
        >>> isinstance([ x*x for x in range(1,5)], Iterable)
        True
生成器不但可以用for循环,还可以被next()函数不断获取下一个值,直到最后抛出StopIteration错误。
可以被next()函数不断返回下一个值的对象成为迭代器Iterator。
生成器都是Iterable对象,但是Iterable对象不一定是迭代器Iterator,如 list、dict、str。
        >>> l = [1,2,3,4,5,6,7]
        >>> l.next()
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        AttributeError: 'list' object has no attribute 'next'
        >>> next(l)
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        TypeError: 'list' object is not an iterator
把list、dict、str等Iterable变成Iterator,可以使用iter()函数:
        >>> from collections import Iterator
        >>> isinstance('abc', Iterator)
        False
        >>> isinstance(iter('abc'), Iterator)
        True
        >>> isinstance([], Iterator)
        False
        >>> isinstance(iter([]), Iterator)
        True
        >>> next('abc')                                     #从这行开始,这块实验其实是有问题的,但是问题在哪,我目前还不知道。
        Traceback (most recent call last):            #在下面使用iter()函数之后,可以使用next()函数进行操作,
          File "<stdin>", line 1, in <module>           #但是操作多次后,结果一直为'a' , 不知道为什么。
        TypeError: 'str' object is not an iterator
        >>> next(iter('abc'))
        'a'
为什么list、dict、tuple、str、set等数据类型不是Iterator呢?
Iterator对象表示的是一个数据流,可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出的StopIteration错误。这个数据流可以看作是一个有序序列,但是却不能提前知道序列的长度,只能不断通过next()函数来实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时才会进行计算。
Iterator甚至可以表示一个无限大的数据流,而list、tuple等对象是永远不可能存储无限大的数据的,例如全体自然数。

迭代器小结:
   1.  可以for循环的对象都是Iterable ,可迭代对象。
   2.  可以作用于next()函数的对象都是Iterator,迭代器,表示是一个惰性计算的序列。
   3.  集合数据类型如dict、list、tuple等对象是Iterable,但是不是Iterator,但是可以通过iter()函数获得Iterator对象。
   
   
for循环本质上就是不断调用next()函数实现的,如:
    for x in [1,2,3,4,5]:
        pass
    等同于
    it = iter([1,2,3,4,5])
    while True:
        try:
            x = next(it)
        except StopIteration:       #遇到StopIteration时则退出循环。
            break