zoukankan      html  css  js  c++  java
  • 迭代器/可迭代对象/生成器

    先上本文主题:

    1. 迭代器一定是可迭代对象,可迭代对象不一定是迭代器;
    2. 可迭代对象要满足什么条件才能使用 for 正确遍历;
    3. 生成器一定是迭代器.

    如何判断是否是迭代器/可迭代对象

    from collections.abc import Iterator,Iterable
    
    t = []
    # 是否为迭代器
    isinstance(t,Iterator)
    # 是否为可迭代对象
    isinstance(t,Iterable)
    

    可迭代对象

    实现了__iter__魔法方法,就是可迭代对象.

    class Test:
      def __iter__(self):
          pass
    
    t = Test()
    
    print(isinstance(t,Iterable)) # True
    print(isinstance(t,Iterator)) # False
    

    迭代器

    实现了__iter____next__魔法方法,就是可迭代对象.

    class Test:
      def __iter__(self):
          pass
    
      def __next__(self):
          pass
    
    t = Test()
    
    print(isinstance(t,Iterable)) # True
    print(isinstance(t,Iterator)) # True
    

    从上面两个条件可以推导出,迭代器一定是可迭代对象

    一个对象要满足什么条件才能被使用 for 进行遍历

    1. 该对象需要是一个可迭代对象,即实现了__iter__方法;
    2. __iter__方法返回一个实现了__next__方法的对象;
    class A:
      def __next__(self):
        return 'hello world'
    
    a = A()
    
    class B:
      def __iter__(self):
          return a
    
    b = B()
    # 每次循环都会调用a的__next__方法获取返回值.
    for i in b:
      print(i)
    

    输出如下:

    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    hello world
    ...
    

    上面两个 class 组合在起义的写法如下:

    class B:
      def __iter__(self):
          return self
    
      def __next__(self):
        return 'hello world'
    
    b = B()
    for i in b:
      print(i)
    

    这里的关键点就是在__iter__方法中返回的self,因为 class 实现了__next__方法,所以返回self正好满足第二个条件.

    生成器和迭代器的关系

    生成器自动实现了迭代器的协议

    为什么这样说呢?
    返回生成器对象一共有两种方式:

    1. 生成器表达式;
    2. 调用含有 yield 的函数.

    以第一种方式为例

    In [1]: a = (i for i in range(10))
    
    In [2]: a.__next__
    Out[2]: <method-wrapper '__next__' of generator object at 0x10d3f2ed0>
    
    In [3]: a.__iter__
    Out[3]: <method-wrapper '__iter__' of generator object at 0x10d3f2ed0>
    

    可以看到,虽然我们并未显示定义,但是生成器表达式确实实现了__iter____next__方法,通过yield关键字定义的生成器同样拥有这样的特性,所以说,生成器自动实现了迭代器的协议.生成器一定是迭代器.

  • 相关阅读:
    超链接标签、链接地址、锚文本及图片标签
    有序无序列表,div盛放逻辑版块,table表格
    函数的默认值与动态参数arguments的总结
    浏览器中常见的html语义化标签
    html基本介绍,了解html与css,html语法和结构
    js函数与作用域,了解函数基本概念
    JavaScrip流程控制之switch选择,for循环
    JavaScript之if流程控制演练,if写在区间内怎么解决
    JavaScript数据类型typeof()和转换
    C++走向远洋——60(十四周阅读程序、STL中的简单容器和迭代器)
  • 原文地址:https://www.cnblogs.com/aloe-n/p/12242493.html
Copyright © 2011-2022 走看看