美文网首页
第六章 迭代器与生成器&列表推倒式

第六章 迭代器与生成器&列表推倒式

作者: 帅气的Lucky | 来源:发表于2021-08-23 19:06 被阅读0次

    一、列表推导式

    1、概述

    列表推导式提供了从序列创建列表的简单途径。

    2、回顾

    只能生成简单的列表

    print(list(range(1,11)))
    

    3、需求

    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

    4、实现

    1. 循环生成列表

      li = []
      for i in range(1, 11):
          li.append(pow(i, 2))
      print(li)
      

      缺点:循环比较繁琐

    2. 列表生成式

      作用

      列表推导式提供了从序列创建列表的简单途径。

    • 一般形式

      li2 = [x * x for x in range(1, 11)]
      print(li2)
      
    • 一般形式加判断

      if 子句作为过滤器

      >>> vec = [2, 4, 6]
      >>> [3*x for x in vec if x > 3]
      [12, 18]
      li3 = [x for x in range(1, 11) if x % 2 == 0]
      print(li3)
      
    • 多层循环

      li4 = [x + y for x in "ABC" for y in "123"]
      print(li4)
      

      拆分

      for x in "ABC":
          for y in "123":
              ret = x + y
      
    • 列表嵌套

      #输出每个值 并将每个值2次方
      vec = [2, 4, 6]
      [[x, x**2] for x in vec]
      [[2, 4], [4, 16], [6, 36]]
      

    5、案例 矩阵转换

    • 以下实例展示了3X4的矩阵列表:

      >>> matrix = [
      ...     [1, 2, 3, 4],
      ...     [5, 6, 7, 8],
      ...     [9, 10, 11, 12],
      ... ]
      
    • 以下实例将3X4的矩阵列表转换为4X3列表:

      >>> [[row[i] for row in matrix] for i in range(4)]
      [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
      

      另外一种实现方法:

      >>> transposed = []
      >>> for i in range(4):
      ...     # the following 3 lines implement the nested listcomp
      ...     transposed_row = []
      ...     for row in matrix:
      ...         transposed_row.append(row[i])
      ...     transposed.append(transposed_row)
      ...
      >>> transposed
      

    二、字典推导式

    可能你见过列表推导时,却没有见过字典推导式,在2.7中才加入的:

    格式:

    d = {key: value for (key, value) in iterable}

    示例

    d = {key: value for key, value in [('a','a'),('b','b')]
    

    三、可迭代对象

    1、概念

    可以直接作用于for循环的对象统称为可迭代对象(Iterable)

    可以用isinstance()去判断一个对象是否是Iterable对象

    2、可以直接作用于for循环的数据类型

    • 集合数据类型(list、tuple、dict、set、string)

    • generator
      a、生成器
      b、带yield的generator function

        Iterable表示可迭代类型
      
    • 引入方法判断是否为 Iterable 可迭代对象

      from collections import Iterable

    from collections import Iterable
    # 格式
    # isinstance(obj, type):判断obj是否属于type类型
    
    print(isinstance([], Iterable))
    print(isinstance((), Iterable))
    print(isinstance({}, Iterable))
    print(isinstance("", Iterable))
    print(isinstance(range(10), Iterable))
    print(isinstance(100, Iterable))
    

    四、迭代器

    1、概念

    1、可以被next()函数调用并返回一个值的对象为迭代器对象
    2、迭代器不但可以用于for,还可以用于next()
    

    2、使用

    使用 iter函数 变成Iterator对象

    • from collections import Iterator

    实例:

    #转成Iterator对象
    li = [1,2,3,4,5]
    g = iter(li)
    print(g, type(g))
    print(next(g))
    print(next(g))
    

    判断是否为迭代器

    可以被next()函数调用并不断返回下一个值的对象称为迭代器(Iterator对象)
    可以使用isinstance()函数判断一个对象是否是Iterator对象

    from  collections import Iterator
    
    print(isinstance([], Iterator))
    print(isinstance((), Iterator))
    print(isinstance({}, Iterator))
    print(isinstance("", Iterator))
    print(isinstance((x for x in range(10)), Iterator))
    

    注意:

    1. 迭代是Python最强大的功能之一,是访问集合元素的一种方式。。
    2. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
    3. 迭代器有两个基本的方法:iter()next()
    4. 不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后跑出一StopIteration错误表示无法继续返回下一个值

    2、为什么list、tuple、dict、string、set等数据类型不是Iterator?

    Iterator对象表示的是一个流数据,Iterator对象可以被next()调用并返回一个数据,直到抛出StopIteration异常错误则停止。可以把数据流看成一个有序的序列,但是不确定这个序列的长度,只能通过next()函数不断计算求值,Iterator可以表示一个无限大的数据流,而list等永远不可能存储无限的数据

    五、生成器

    1、概述

    在 Python 中,使用了 yield 的函数被称为生成器(generator)。生成器也实现了迭代器的功能

    跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

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

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

    2、注意

    • 函数时顺序执行,遇到return语句后者最后一行代码就返回

    • 如果想让一个函数变为生成器函数,只需将函数中的return改为yield

    • 执行生成器函数不会执行函数代码,得到一个生成器

    • 在每次调用next()的时候,会执行生成器函数,遇到yield语句就返回,如果再次执行next()

    3、实现

    • 使用列表推倒式实现

      #普通列表 消耗资源
      mylist = [x for x in range(100000)]
      for i in mylist:
          print(i)
      #对比执行效率
      #生成器  节省资源
      mylist = (x for x in range(100000))
      for i in mylist:
          print(i) 
      
    • 使用函数实现

      1. yield
      2. Next()

      使用yield关键字修饰的值 下面的代码不会再执行 只有再次调用next函数的时候 会再次执行

      #没有生成器的go方法 调用的时候一口气都跑完  消耗资源
      def go():
          print(1)
          print(2)
          print(3)
      #有生成的函数 可以实现 next一次 走一次
      def go():
          print(1)
          yield 10 #执行print1,返回10,next
          print(2)
          yield 20#执行print2,返回20,next
          print(3)
          yield 30#执行print3,返回30,next
      
      def createlist():
          for i  in range(100):
              print(i)
              yield  i
      
      X=createlist()
      print(type(X))
      next(X)
      next(X)
      next(X)
      next(X)
      

    4、使用 yield 实现斐波那契数列

    import sys
     
    def fibonacci(n): # 生成器函数 - 斐波那契
        a, b, counter = 0, 1, 0
        while True:
            if (counter > n): 
                return
            yield a
            a, b = b, a + b
            counter += 1
    f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
     
    while True:
        try:
            print (next(f), end=" ")
        except StopIteration:
            sys.exit()
    

    相关文章

      网友评论

          本文标题:第六章 迭代器与生成器&列表推倒式

          本文链接:https://www.haomeiwen.com/subject/gqililtx.html