• python疑难问题---12、python生成器


    python疑难问题---12、python生成器

    一、总结

    一句话总结:

    在Python中,一边循环一边计算的机制,称为生成器:generator。
    g3 = (x+3 for x in range(20))
    for i in g3:
        print(i)
    
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    1、为什么要有生成器?

    我又想要得到庞大的数据,又想让它占用空间少,那就用生成器!

    2、Python创建生成器两种方式?

    A、生成器推导式:第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:g = (x * x for x in range(20))
    B、yield关键字:如果一个函数中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator函数。调用函数就是创建了一个生成器(generator)对象。

    3、生成器的工作原理?

    (1)、生成器(generator)能够迭代的关键是它有一个next()方法,工作原理就是通过重复调用next()方法,直到捕获一个异常。
    (2)、带有 yield 的函数不再是一个普通函数,而是一个生成器generator。可用next()调用生成器对象来取值。next方法的两种方式: t.__next__() 或 next(t)。
    (3)、yield相当于 return 返回一个值,并且记住这个返回的位置,下次迭代时,代码从yield的下一条语句开始执行。

    二、python生成器

    博客对应课程的视频位置:12、python生成器-范仁义-读书编程笔记
    https://www.fanrenyi.com/video/32/370

    1、生成器定义

    在Python中,一边循环一边计算的机制,称为生成器:generator。

    2、为什么要有生成器

    列表所有数据都在内存中,如果有海量数据的话将会非常耗内存。

    如:仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

    如果列表元素按照某种算法推算出来,那我们就可以在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。

    简单一句话:

    我又想要得到庞大的数据,又想让它占用空间少,那就用生成器!

    3、如何创建生成器

    A、生成器推导式

    第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

    In [1]:
    L = [x * x for x in range(20)]
    print(L)
    print(type(L))
    
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361]
    <class 'list'>
    
    In [2]:
    g = (x * x for x in range(20))
    print(g)
    print(type(g))
    
    <generator object <genexpr> at 0x000002B10654E5C8>
    <class 'generator'>
    
    In [3]:
    print(next(g))
    
    0
    
    In [4]:
    print(next(g))
    
    1
    
    In [5]:
    print(next(g))
    
    4
    
    In [6]:
    print(g.__next__())
    
    9
    
    In [7]:
    print(g.__next__())
    print(next(g))
    print('暂停一下')
    print(next(g))
    print(next(g))
    print(g.__next__())
    
    16
    25
    暂停一下
    36
    49
    64
    

    创建L和g的区别仅在于最外层的[]和(),L是一个list,而g是一个generator。

    B、yield关键字

    方法二, 如果一个函数中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator。调用函数就是创建了一个生成器(generator)对象。

    In [8]:
    def f1(max):
      n=0
      while n<max:
        yield n
        n+=1
    f=f1(6)
    print(f)
    
    <generator object f1 at 0x000002B10654E848>
    
    In [9]:
    print(f.__next__())
    print(next(f))
    print('暂停一下')
    print(f.__next__())
    print(next(f))
    
    0
    1
    暂停一下
    2
    3
    
    In [10]:
    print(f.__next__())
    print(next(f))
    print('暂停一下')
    print(f.__next__())
    print(next(f))
    
    4
    5
    暂停一下
    
    ---------------------------------------------------------------------------
    StopIteration                             Traceback (most recent call last)
    <ipython-input-10-a62ed49ebaef> in <module>
          2 print(next(f))
          3 print('暂停一下')
    ----> 4 print(f.__next__())
          5 print(next(f))
    
    StopIteration: 

    如果生成器里面的数据读完了,继续执行next方法,会报StopIteration的错误

    4、生成器的工作原理

    (1)生成器(generator)能够迭代的关键是它有一个next()方法,

      工作原理就是通过重复调用next()方法,直到捕获一个异常。

    (2)带有 yield 的函数不再是一个普通函数,而是一个生成器generator。

      可用next()调用生成器对象来取值。next方法的两种方式: t.__next__() 或 next(t)。

      可用for 循环获取返回值(每执行一次,取生成器里面一个值)

      (基本上不会用next()来获取下一个返回值,而是直接使用for循环来迭代)。

    (3)yield相当于 return 返回一个值,并且记住这个返回的位置,下次迭代时,代码从yield的下一条语句开始执行。

    5、for循环读取生成器的值

    for循环 循环调用next方法

    In [11]:
    g2 = (x ** 3 for x in range(20))
    
    In [12]:
    for i in range(5):
        print(next(g2))
    
    0
    1
    8
    27
    64
    
    In [13]:
    for i in range(5):
        print(next(g2))
    
    125
    216
    343
    512
    729
    

    直接使用for循环来迭代

    因为生成器是一个迭代器,所以可以直接用for循环迭代

    In [14]:
    g3 = (x+3 for x in range(20))
    
    In [15]:
    for i in g3:
        print(i)
    
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    In [16]:
    g4 = (x+3 for x in range(20))
    
    In [17]:
    # 如果只想从生成器中取部分数据,可以直接break打断循环
    n = 10
    for i in g4:
        print(i)
        if(n<2):
            break
        n-=1
    
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    In [ ]:
     

    在Python中,一边循环一边计算的机制,称为生成器:generator。

    系列博客对应课程视频地址:
    1、遍历列表的三种方式-范仁义-读书编程笔记
    https://www.fanrenyi.com/video/32/293
    2、字典排序-范仁义-读书编程笔记
    https://www.fanrenyi.com/video/32/294
    3、可变和不可变数据类型-范仁义-读书编程笔记
    https://www.fanrenyi.com/video/32/295
    4、python文件处理-范仁义-读书编程笔记
    https://www.fanrenyi.com/video/32/305
    5、二维列表初始化-范仁义-读书编程笔记
    https://www.fanrenyi.com/video/32/306
    6、python中浅拷贝和深度拷贝-范仁义-读书编程笔记
    https://www.fanrenyi.com/video/32/307
    7、python中的with...as...-范仁义-读书编程笔记
    https://www.fanrenyi.com/video/32/320
    8、只有一个数的元组表示-范仁义-读书编程笔记
    https://www.fanrenyi.com/video/32/343
    9、Python类中call函数的作用-范仁义-读书编程笔记
    https://www.fanrenyi.com/video/32/361
    10、python遍历字典的几种方式-范仁义-读书编程笔记
    https://www.fanrenyi.com/video/32/368
    11、python内嵌for...in循环-范仁义-读书编程笔记
    https://www.fanrenyi.com/video/32/369
    12、python生成器-范仁义-读书编程笔记
    https://www.fanrenyi.com/video/32/370
    13、Python切片操作-范仁义-读书编程笔记
    https://www.fanrenyi.com/video/32/377
     
    我的旨在学过的东西不再忘记(主要使用艾宾浩斯遗忘曲线算法及其它智能学习复习算法)的偏公益性质的完全免费的编程视频学习网站: fanrenyi.com;有各种前端、后端、算法、大数据、人工智能等课程。
    博主25岁,前端后端算法大数据人工智能都有兴趣。
    大家有啥都可以加博主联系方式(qq404006308,微信fan404006308)互相交流。工作、生活、心境,可以互相启迪。
    聊技术,交朋友,修心境,qq404006308,微信fan404006308
    26岁,真心找女朋友,非诚勿扰,微信fan404006308,qq404006308
    人工智能群:939687837

    作者相关推荐

  • 相关阅读:
    睁大你的眼睛,警惕职业生涯中的“红灯”
    几则好玩的脑筋急转弯
    File.Delete()的解决
    Powershell之True或False
    发送邮件
    IE与CSS兼容性
    WSS
    File.Delete()
    添加field部署
    css加载
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/13849673.html
Copyright © 2020-2023  润新知