• 迭代器和生成器


    • 迭代器(Interators)

    • 定义:通过loop的方式,将数据重复地进行通过内置方法或者代码对数据进行处理,每一次迭代的数据都要依赖于上一组数据,能够实现       上述任务的工具就被称之为迭代器

    • 与递归(Recursion)的区别

    • 递归是在定义函数内部调用函数自身,是一种先回溯再递推的过程。而迭代则是在函数内部使用loop语句通过循环来使得数据一步一步基于前一步的旧数据实现代码功能的过程。

    • 来通过求一个数的阶乘的代码实现来观察其中端倪
    • ############ 递推 ##############
      
      def factorial_num(x):
          if x == 0:
              return 1
          return x * factorial_num(x-1)   # 调用了定义的函数,并在前面给出了最后一步递归数据的取值
      
      res = factorial_num(5)
      print(res)
      
      ############ 迭代 ##############
      
      def factorial_num1(y):
          res = 1
          if y == 0:
              return res
          for i in range(2,y+1):          # 通过循环语句来实现迭代的功能
                  res *= i
          return res
      print(factorial_num1(5))

      一般来说递归方法可以用在代码量比较少的程序之中,但由于其时间复杂度很高的缘故,一般在中大型程序中一般使用迭代方法

    • 迭代是基于loop循环的功能,在之前的列表字典元组等数据类型的取值中,其本质就是for循环,显然它们是相同的,因此我们可以发现以下数据类型可以通过迭代取值:
      1. 字符串   

      2. 列表

      3. 字典

      4. 元组

      5. 集合

    • 上述我们之前所说的容器类型现在有一个比较标准的术语叫做可迭代对象(文件类型也是可迭代对象,同时它也是迭代器对象)

    • 更加严谨一点说,只有内置方法有__iter__的数据类型可以被称作可迭代对象,更为重要的是可迭代对象通过)__iter__方法可以输出为迭代器对象。

    • 迭代器取值的方法

    • l = [1,2,3,4]               # 列表是可迭代对象
      iter_l = l.__iter__()       # 要想迭代取值 必须用迭代器对象取值,所以要将可迭代对象转化为迭代器对象
      print(iter_l.__next__())    
      print(iter_l.__next__())
      print(iter_l.__next__())
      print(iter_l.__next__())    # 如果取完了 直接报错,只能往后取不能后退

      值得注意的是,无论迭代器对象执行多少次,__iter__得到的还是迭代器本身

    • 如何处理取值完毕后的报错行为

    • l = [1,2,3,4,5,6,7,8]
      iter_l = l.__iter__()
      while True:
          try:
              print(iter_l.__next__())
          except StopIteration:               # 报错时结束循环,不会出现报错信息
              break
    • for循环的本质

      1. 将in后面的对象通过__iter__方法将其变为迭代器对象
      2. 再使用__next__方法进行从前往后的迭代取值
      3. 内部报错StopIteration后,自动结束循环
    • 生成器

    • 定义:用户自定义的迭代器,本质就是迭代器

    • def func():
          print('first')
          yield  666,67           # 函数内如果有yield关键字,那么加括号执行函数的时候并不会触发函数体代码的运行,并且假如是多组数据会以元组的形式输出
          print('second')
          yield  777
          print('third')
          yield  888
          print('forth')
          yield 999
      print(func().__next__())
      g = func()                  # 生成器初始化:将函数变成迭代器对象
      print(g.__next__())
    • 另一种设置生成器的方式

    • res = (i for i in range(1,100000000) if i != 4)  # 生成器表达式
      print(res)
      """
      生成器不会主动执行任何一行代码
      必须通过__next__触发代码的运行
      """
      print(res.__next__())
      print(res.__next__())
      print(res.__next__())
      print(res.__next__())
  • 相关阅读:
    BootstrapValidator 解决多属性被同时校验问题《转》
    SSRS 浮动表头设置
    ToString(string format)输出格式简述
    配置AutoMapper映射规则《转》
    IE浏览器上传图片预览兼容(IE 7 8 9 10 11)
    SQL : IN 和 Exists 的区别
    BitArray简单例子
    Rx.net 例子——(1)基础
    C# Pinvoke判断是UEFI模式还是BIOS模式
    wpf Route Event Code Snippet
  • 原文地址:https://www.cnblogs.com/ITchemist/p/11192306.html
Copyright © 2020-2023  润新知