zoukankan      html  css  js  c++  java
  • 迭代器和生成器

    迭代器和生成器

    1.迭代器

    1.1 迭代器类型的定义;

    • 当类中定义了__iter____nxet__两个方法。

    • __iter__方法需要返回本身即self

    • __nxet__方法,返回下一个数据,如果没有数据了,则需要抛出一个StopIteration的异常。

    • # 创建迭代器类型
      class IT(object):
          def __init__(self):
              self.counter=0
      
          def __iter__(self):
              return self#返回self
          def __next__(self):
              self.counter+=1
              if self.counter==3:
                  raise StopIteration#没有数据时抛出异常
              return self.counter#返回下一个数据。
      

    1.2 迭代器对象

    • 根据实例化创建一个迭代对象

    • # 根据实例化创建迭代器对象
      
      obj1=IT()
      
      v1=next(obj1)#next内置函数直接调用,obj1.__next__()
      print(v1)
      
      v2=obj1.__next__()
      print(v2)
      v3=next(obj1)
      print(v3)# 抛出异常,因为没有值了;
      
    • image-20211127145602993

    • 使用for循环迭代器对象

      for 循环内部在循环时,先执行__iter__方法,获取一个迭代对象,然后不断执行next()取值(有异常StopIteration则循环终止)

      # 迭代器对象支持通过next()取值,取值结束则会自动抛出StopIteration
      obj=IT()
      for item in obj:#首先会执行obj的__iter__方法,并获取返回值,一直去反复的执行next(对象)
          print(item)
      

    1.3 补充dir()函数

    • dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。如果参数包含方法__dir__(),该方法将被调用。如果参数不包含__dir__(),该方法将最大限度地收集参数信息。

    • 语法
      dir([object])
      # 参数可以是对象、变量、类型。
      
    • 返回值

      模块的属性列表。

    • image-20211127151243671

    2.生成器

    2.1 定义

    • 在函数体中使用了yield的函数成为生成器(generator);

    • 生成器是一种特殊迭代器

    • 在调用生成器运行的过程中,每次遇到yield时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在**下一次执行 next() **方法时从当前位置继续运行。

    • 调用一个生成器函数,返回的是一个生成器对象(迭代器对象)

    • 使用生成器可以节省内存

    • def func():
          print(111)
          yield 1
      
      obj1=func()
      print(obj1)#<generator object func at 0x0000000001E2E190>
      # 打印的是生成器对象;
      
    • 执行生成器函数,返回的是生成器对象

    2.2 执行生成器

    • def func():
          print(111)
          yield 1
      
          print(222)
          yield 2
      
          print(333)
          yield 3
      obj1=func()
      print(obj1)#<generator object func at 0x0000000001E2E190>
      
      next(obj1)# 111
      next(obj1)# 222从yield之后的位置开始执行
      
      n1=next(obj1)# 333
      print(n1)# 3 获得yield返回的值
      next(obj1)# StopIteration超出范围
      

    2.3 基于for循环执行生成器

    • data=func()
      for item in data:
          # next(data),相当于内部执行next(data)
          print(item)
      
    • image-20211127153805740

    2.4 生成器的应用场景

    • image-20211127154037307

    补充:生成器可以使用send()给生成其中赋值;

    3.可迭代对象

    3.1 定义

    • 如果一个类中有__iter__方法,返回的是迭代器对象;则我们成这个类创建的对象为可迭代对象。

    • 可迭代对象是可以用来for循环的,再循环内部其实是先执行__iter__方法,获取迭代器对象。然后再在内部执行迭代器对象的next功能逐步取值。

    • class Foo(object):
          def __iter__(self):
              return 迭代器对象
      obj=Foo()
      #obj就是可迭代对象
      
      for item in obj:
          pass
      
    • 通常迭代器会和可迭代对象一起使用

      # 定义迭代器对象
      class IT(object):
          def __init__(self):
              self.counter=0
      
          def __iter__(self):
              return self
          def __next__(self):
              self.counter+=1
              if self.counter==3:
                  raise StopIteration
              return self.counter
      
      class Foo(object):
          def __iter__(self):
              return IT()
      
      obj=Foo()
      for item in obj:
          print(item)
      

      image-20211127155912447

    • 我们使用的range函数就是可迭代对象,因为他包含了__iter__方法

      image-20211127160630958

    3.2 常见的可迭代对象

    • 能被for循环的数据类型都是可迭代对象;

      • 字符串
      • 列表
      • 元组
      • 字典
      • 集合
    • image-20211127161030328

    3.3 判断是否是迭代器

    from collections.abc import Iterator,Iterable
    v1=[1,2,3]
    print(isinstance(v1,Iterator)) #false  判断是否是迭代器  依据:__iter__ 和 __next__
    v2=v1.__iter__()
    print(isinstance(v2,Iterator))# True
    # 判断可迭代
    print(isinstance(v1,Iterable))# True   依据是否有__iter__且返回迭代器对象,一般和上面的判断结合使用
    print(isinstance(v2,Iterable))# True
    

    3.4 补充:isinstance函数

    • isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type()。

    • isinstance() 与 type() 区别:
      • type() 不会认为子类是一种父类类型,不考虑继承关系。
      • isinstance() 会认为子类是一种父类类型,考虑继承关系。
    • 如果要判断两个类型是否相同推荐使用 isinstance()。

    • 语法
      isinstance(object, classinfo)
      # object -- 实例对象。
      # classinfo -- 可以是直接或间接类名、基本类型或者由它们组成的元组。
      
    • 返回值

      如果对象的类型与参数二的类型(classinfo)相同则返回 True,否则返回 False。。

      image-20211127162423312

    每天都是更接近成功的一天;

  • 相关阅读:
    SSRS_NOTE
    github快速使用指南
    Serving 404s instead of errors solved :)
    如何提高LINQtoSQL延时加载的性能
    SqlServer开发利器—SQL Prompt5
    内核通知链 学习笔记 arm
    Excel报表之js版
    JS修改Table中Td的值。
    什么时候能忙完~
    JS修改Table中Td的值(修改)
  • 原文地址:https://www.cnblogs.com/Blogwj123/p/15612256.html
Copyright © 2011-2022 走看看