zoukankan      html  css  js  c++  java
  • 迭代器详解

    1.迭代器Iterator

    迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
     
    迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据。实际上,在使用next()函数的时候,调用的就是迭代器对象的__next__方法(Python3中是对象的__next__方法,Python2中是对象的next()方法)。所以,我们要想构造一个迭代器,就要实现它的__next__方法。但这还不够,python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现__iter__方法,而__iter__方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的__iter__方法返回自身即可。
    一个实现了__iter__方法和__next__方法的对象,就是迭代器。
     
    示例代码如下:
    class FibIterator(object):
        """斐波那契数列迭代器"""
        def __init__(self, n):
            """
            :param n: int, 指明生成数列的前n个数
            """
            self.n = n
            # current用来保存当前生成到数列中的第几个数了
            self.current = 0
            # num1用来保存前前一个数,初始值为数列中的第一个数0
            self.num1 = 0
            # num2用来保存前一个数,初始值为数列中的第二个数1
            self.num2 = 1
    
        def __next__(self):
            """被next()函数调用来获取下一个数"""
            if self.current < self.n:
                num = self.num1
                self.num1, self.num2 = self.num2, self.num1+self.num2
                self.current += 1
                return num
            else:
                raise StopIteration
    
        def __iter__(self):
            """迭代器的__iter__返回自身即可"""
            return self
    
    
    if __name__ == '__main__':
        fib = FibIterator(10)
        for num in fib:
            print(num, end=" ")

    2. 如何判断一个对象是否是迭代器

    可以使用 isinstance() 判断一个对象是否是 Iterator 对象:
    In [1]: from collections import Iterator
    
    In [2]: isinstance([], Iterator)
    Out[3]: False
    
    In [4]: isinstance(iter([]), Iterator)
    Out[5]: True
    
    In [6]: isinstance(iter("abc"), Iterator)
    Out[7]: True

    3. for...in...循环的本质

    for item in Iterable 循环的本质就是先通过iter()函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束。
     

    4. 迭代器的应用场景

    举个例子,比如,数学中有个著名的斐波拉契数列(Fibonacci),数列中第一个数为0,第二个数为1,其后的每一个数都可由前两个数相加得到:
    0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
    现在我们想要通过for...in...循环来遍历迭代斐波那契数列中的前n个数。那么这个斐波那契数列我们就可以用迭代器来实现,每次迭代都通过数学计算来生成下一个数。
    class FibIterator(object):
      """斐波那契数列迭代器"""
      def __init__(self, n):
        """
        :param n: int, 指明生成数列的前n个数
        """
        self.n = n
        # current用来保存当前生成到数列中的第几个数了     self.current = 0     # num1用来保存前前一个数,初始值为数列中的第一个数0     self.num1 = 0     # num2用来保存前一个数,初始值为数列中的第二个数1     self.num2 = 1   def __next__(self):     """被next()函数调用来获取下一个数"""     if self.current < self.n:       num = self.num1       self.num1, self.num2 = self.num2, self.num1+self.num2       self.current += 1       return num     else:       raise StopIteration   def __iter__(self):     """迭代器的__iter__返回自身即可"""     return self if __name__ == '__main__':   fib = FibIterator(10)   for num in fib:     print(num, end=" ")

    5. 并不是只有for循环能接收可迭代对象

    除了for循环能接收可迭代对象,list、tuple等也能接收。
    li = list(FibIterator(15))
    print(li)
    tp = tuple(FibIterator(6))
    print(tp)
  • 相关阅读:
    WCF后续之旅(3): WCF Service Mode Layer 的中枢—Dispatcher
    .Net 2.0对文件传输协议(FTP)操作(上传,下载,新建,删除,FTP间传送文件等)
    我的WCF之旅(13):创建基于MSMQ的Responsive Service
    .net程序集强名称签名实践
    WCF后续之旅(8):通过WCF Extension 实现与MS Enterprise Library Policy Injection Application Block 的集成
    .Net 2.0对文件传输协议(FTP)操作(上传,下载,新建,删除,FTP间传送文件等) 2
    WCF后续之旅(6): 通过WCF Extension实现Context信息的传递
    SilverlightCatchWcfError
    WCF后续之旅(7):通过WCF Extension实现和Enterprise Library Unity Container的集成
    WCF后续之旅(4):WCF Extension Point 概览
  • 原文地址:https://www.cnblogs.com/new-rain/p/9992091.html
Copyright © 2011-2022 走看看