当前位置 博文首页 > zy010101博客:Python——迭代器

    zy010101博客:Python——迭代器

    作者:[db:作者] 时间:2021-06-26 18:19

    迭代器模式

    当扫描内存中放不下的数据集时,我们要找到一种惰性获取数据项的方式,即按需一次获取一个数据项。这就是迭代器模式(Iterator pattern)。C/C++这种语言并没有在语法层面直接实现迭代器模式,需要手动实现。python直接内置了迭代器模式。
    python2.3中正式引入yield关键字,该关键字用来构建生成器(generator),其作用和迭代器一样。
    所有生成器都是迭代器,因为生成器完全实现了迭代器接口。
    迭代器用于从集合中取出元素;而生成器用于“凭空”生成元素。
    不过在python中,大多数时候把迭代器和生成器视为同一个概念。在python3中,现在range()函数返回的是类似生成器的对象,而不在是列表。

    可迭代对象

    python中的序列对象(包括字符串,元组,列表,字典,集合)都是可以迭代的。这是因为内置的iter函数。
    内置的 iter 函数有以下作用。
    (1) 检查对象是否实现了 __iter__ 方法,如果实现了就调用它,获取一个迭代器。
    (2) 如果没有实现 __iter__ 方法,但是实现了 __getitem__ 方法,Python 会创建一个迭代器,尝试按顺序(从索引 0 开始)获取元素。
    (3) 如果尝试失败,Python 抛出 TypeError 异常,通常会提示“C object is not iterable”(C对象不可迭代),其中 C 是目标对象所属的类。

    __getitem__方法可能之后会被弃用,python3.8.2该方法存在。
    

    使用 iter 内置函数可以获取迭代器对象。如果对象实现了能返回迭代器的 __iter__方法,那么对象就是可迭代的。

    我们要明确可迭代的对象和迭代器之间的关系:Python 从可迭代的对象中获取迭代器。

    迭代器对象

    迭代器是这样的对象:实现了无参数的 __next__ 方法,返回序列中的下一个元素;如果没有元素了,那么抛出 StopIteration 异常。Python 中的迭代器还实现了 __iter__ 方法,因此迭代器本身也可以迭代。
    因为迭代器只需 __next__ 和 __iter__ 两个方法,所以除了调用 next() 方法,以及捕获StopIteration 异常之外,没有办法检查是否还有遗留的元素。此外,也没有办法“还原”迭代器。如果想再次迭代,那就要调用 iter(…),传入之前构建迭代器的可迭代对象。传入迭代器本身没用,因为前面说过 Iterator.__iter__ 方法的实现方式是返回实例本身,所以传入迭代器无法还原已经耗尽的迭代器。

    下面的例子说明了如何从可迭代对象中获取迭代器对象,进行迭代。

    >>> L = [1,2,3]
    >>> I = iter(L)     # 获取迭代器对象
    >>> next(I)         # next方法进行迭代
    1
    >>> next(I)
    2
    >>> next(I)
    3
    >>> next(I)         # 抛出StopIteration异常
    Traceback (most recent call last)   :
      File "<stdin>", line 1, in <module>
    StopIteration
    

    一个更加实际的例子,使用while循环模拟for循环。

    L = [1, 2, 3]
    for i in L:
        print(i)
    

    执行结果:

    1
    2
    3
    

    模拟for循环

    L = [1, 2, 3]
    I = iter(L)
    while True:
        try:
            print(next(I))
        except StopIteration:
            del I
            break
    

    执行结果:

    1
    2
    3
    

    for循环和可迭代对象之间的关系

    for循环会使用迭代协议来遍历可迭代对象中的每一个项。它首先把可迭代对象传入iter函数来获取一个迭代器,然后在每次迭代中调用该对象的__next__方法(python2中调用next方法),并且捕获StopIteration异常,从而决定何时停止循环。支持迭代协议的任何对象,都可以用于for循环和其他上下文中。

    python中的迭代上下文

    迭代上下文包括for循环,列表推导,内置in运算符,内置函数sorted,sum,any,all,除此之外还包括list,tuple,字符串join方法以及序列赋值运算,所有这些都使用了迭代协议来一次处理一个元素。

    下一篇:没有了