第十三天 生成器和生成器函数, 列表推导式

一.生成器

生成器Generator

  本质:迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现)

     特点:惰性运算,开发者自定义

python中提供的生成器:

  1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行

  2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表

python中有三种方式来获取生成器的:

  1. 通过生成器函数

  2. 通过各种推导式来实现生成器

  3. 通过数据的转换也可以获取生成器

  

  yield和return的效果是一样的. 但yield是分段来执行一个函数. 而return直接停止执行函数

  由于函数中存在了yield. 那么这个函数就是一个生成器函数. 这个时候. 我们再执行这个函数的时候. 就不再是函数的执行了. 而是获取这个生成器.如何使用呢? 想想迭代器. 生成器的本质是迭代器. 所以. 我们可以直接执行__next__()来执行以下生成器.

  

  当程序运行完最后一个yield. 那么后面继续进行__next__()程序会报错

  

  生成器的作用:节省内存

  

  区别: 第一种是直接一次性全部拿出来. 会很占⽤用内存.第二种使用生成器. 一次就一个. 用多少生成多少. 生成器是一个一个的指向下一个. 不会回去, __next__()到哪, 指针就指到哪儿.下一次继续获取指针指向的值.

Send()方法:

  send和__next__()一样都可以让生成器执行到下一个yield

  send 和 __next__()的区别:

    1. send和next()都是让生成器向下走一次

    2. send可以给上一个yield的位置传递值, 不能给最后一个yield发送值. 在第一次执行生成器代码的时候不能使用send(),必须要用__next__()获取一下值

  使用send的注意事项

     1. 第一次使用生成器的时候 是用next获取下一个值

     2. 最后一个yield不能接受外部的值

    

  生成器可以使用for循环获取内部元素:

  

二.列表推导式,生成器表达式以及其他推导式

 列表推导式

        列表推导式,最终给你的式列表

           列表推导式常用语法:

        [最终结果(变量)  for  变量  in  可迭代对象]

  示例生成列表,里面装1-14的数据
  
 注意:         
  列表推导式是通过一行来构建你要的列表, 列表推导式看起来代码简单. 但是出现错误之后很难排查.
   筛选模式
      [结果 for 变量 in 可迭代对象 if条件]
  

生成器表达式:

   生成器表达式和列表推导式的语法基本上是一样的. 只是把[]替换成()。
打印的结果就是一个生成器. 我们可以使用for循环来循环这个生成器
 示例:

 生成器表达式也可以进行筛选
  
生成器表达式和列表推导式的区别:
  1. 列表推导式比较耗内存. 一次性加载. 生成器表达式几乎不占用内存. 使用的时候才分配和使用内存
  2. 得到的值不一样. 列表推导式得到的是一个列表. 生成器表达式获取的是一个生成器.

举个例子:同样一篮子鸡蛋. 

  列表推导式: 直接拿到一篮⼦鸡蛋. 

  生成器表达式: 拿到一个老母鸡. 需要鸡蛋就给你下鸡蛋

生成器的惰性机制:

  生成器只有在访问的时候才取值. 说白了. 你找他要,他才给你值. 不找他要, 他是不会执行的.
深坑  ==》  生成器,要值得时候才拿值
  

字典推导式:

    推导出的是字典
  

  
集合推导式:
     集合推导式可以帮我们直接生成一个集合. 集合的特点: 无序, 不重复. 所以集合推导式自带去重功能
  
总结: 
  推导式有, 列表推导式, 字典推导式, 集合推导式, 没有元组推导式
  生成器表达式: (结果 for 变量 in 可迭代对象 if 条件筛选)
  生成器表达式可以直接获取到生成器对象. 生成器对象可以直接进行for循环. 生成器具有惰性机制.

面试题(*****)

    

 





 
 
 
 
 





 
 
 
 
原文地址:https://www.cnblogs.com/mwhylj/p/9332957.html