zoukankan      html  css  js  c++  java
  • Python迭代器笔记

    python中的三大器有迭代器,生成器,装饰器,本文重点讲解下迭代器的概念,使用,自定义迭代器等的介绍。

    1.概念:

      迭代器是一个对象,一个可以记住遍历位置的对象,迭代器对象从集合的第一个元素开始访问,直到所有元素被访问完结束,迭代器只能往前,不能后退,实质是具备了__next__和__iter__方法的对象

    2.可迭代对象:

      可以通过for in 等类似操作进行遍历取值的对象,本质是具备了__iter__方法的对象,因为__iter__方法提供了迭代器,实现了遍历位置的记录。在迭代一个可迭代对象的时候,实际上就是先获取该对象提供的一个迭代器,然后通过这个迭代器来依次获取对象中的每一个数据。

    3.代码实现:

    3.1通过isinstance()判断

    In [1]: from collections import Iterable
    
    In [2]: isinstance({},Iterable)
    Out[2]: True
    
    In [3]: isinstance((),Iterable)
    Out[3]: True
    
    In [4]: isinstance("",Iterable)
    Out[4]: True
    
    In [5]: for item in {}:
       ...:     pass
       ...: 
    
    In [6]: for item in "":
       ...:     pass
       ...: 
    
    In [7]: for item in ():
       ...:     pass
       ...: 

    3.2 for in的本质

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

    li = [100, 200, 300, 400]
    # for num in li:
    #     print(num)
    
    
    # 1. 通过调用可迭代对象的__iter__()获取迭代器
    # 2. 对迭代器调用__next__进行迭代操作,
    #     如果没有抛出StopIteration异常,表示迭代没有结束,把获取到的数据元素放到变量中
    #     如果抛出了异常,表示迭代结束,退出执行
    # 3. 执行循环体
    # 4. 跳转到第2步执行
    
    iterator = li.__iter__()
    
    while True:
        try:
            num = iterator.__next__()
        except StopIteration:
            break
        else:
            print(num)

    3.3 自定义迭代器

    class MyIterable(object):
        def __init__(self):
            self.container = [] # 定义一个容器
    
        def add(self, item):
            self.container.append(item)
    
        def __iter__(self):
            return Iterator(self.container) # 返回一个迭代器
    
    
    class Iterator(object):
        def __init__(self, container):
            self.container = container
            self.i = 0
    
        def __next__(self):
            if self.i < len(self.container):
                count = self.i
                self.i += 1
                return self.container[count]
            else:
                raise StopIteration
    
        def __iter__(self):
            pass
    
    
    mi = MyIterable()
    it = mi.__iter__()
    mi.add(1)
    mi.add(2)
    mi.add(3)
    
    for item in mi:
        print(item)
    
    from collections import Iterator
    
    print(isinstance(it, Iterator))

    3.4 合并迭代器

    Python要求定义的迭代器必须实现__iter__(self),并且返回self。通常,一个可迭代对象的迭代器都是固定的,并且,类与类之间需要距离性,对象之间需要相似性,所以通常可迭代对象和迭代器写在一起,就是下面的。

    class MyIterable(object):
        def __init__(self):
            self.container = []
            self.i = 0
    
        def add(self, item):
            self.container.append(item)
    
        def __next__(self):
            if self.i < len(self.container):
                count = self.i
                self.i += 1
                return self.container[count]
            else:
                raise StopIteration
    
        def __iter__(self):
            return self
    
    
    mi = MyIterable()
    mi.add(1)
    mi.add(2)
    mi.add(3)
    
    for item in mi:
        print(item)

     3.5 迭代器应用场景之实现菲波那切数列

      我们发现迭代器最核心的功能就是可以通过next()函数的调用来返回下一个数据值。如果每次返回的数据值不是在一个已有的数据集合中读取的,而是通过程序按照一定的规律计算生成的,那么也就意味着可以不用再依赖一个已有的数据集合,也就是说不用再将所有要迭代的数据都一次性缓存下来供后续依次读取,这样可以节省大量的存储(内存)空间。

    class Fib(object):
        def __init__(self, num):
            self.num = num
            self.num1 = 0
            self.num2 = 1
            self.i = 0
    
        def __next__(self):
            if self.i < self.num:
                self.i += 1
                temp = self.num1
                self.num1, self.num2 = self.num2, self.num1 + self.num2
                return temp
            else:
                raise StopIteration
    
        def __iter__(self):
            return self
    
    
    fib = Fib(7)
    print(list(fib))

     4.iter()函数与next()函数

    对于可迭代对象,我们可以通过iter()函数获取这些可迭代对象的迭代器。然后我们可以对获取到的迭代器不断使用next()函数来获取下一条数据。iter()函数实际上就是调用了可迭代对象的__iter__方法。

    >> li = [1,2,3]
    >>> li_iter = iter(li)
    >>> next(li_iter)
    1
    >>> next(li_iter)
    2
    >>> next(li_iter)
    3
    >>> next(li_iter)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    >>>
  • 相关阅读:
    hdu 1032 水题也wrong 两次(于是乎更有刷水题的必要了)
    淘宝刷钻员
    hdu 4006 求第K大的数 优先队列
    骗子满天飞
    hdu 2115 :I Love This Game(Presentation Error容易输出wrong)
    hdu 1048 (map的使用)
    hdu 1722 数论题
    hdu 1237 简单计算器
    Android编码规范
    xamarin开发实例(一) android PC 基于Tcp双向通信
  • 原文地址:https://www.cnblogs.com/greatfish/p/5839531.html
Copyright © 2011-2022 走看看