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)
  • 相关阅读:
    CF 461B Appleman and Tree
    POJ 1821 Fence
    NOIP 2012 开车旅行
    CF 494B Obsessive String
    BZOJ2337 XOR和路径
    CF 24D Broken robot
    POJ 1952 BUY LOW, BUY LOWER
    SPOJ NAPTIME Naptime
    POJ 3585
    CF 453B Little Pony and Harmony Chest
  • 原文地址:https://www.cnblogs.com/new-rain/p/9992091.html
Copyright © 2011-2022 走看看