• ⽣成器和⽣成器表达式


    一丶生成器和生成器函数

    什么是⽣成器. ⽣成器实质就是迭代器.
    在python中有三种⽅式来获取⽣成器:

    1. 通过⽣成器函数
    2. 通过各种推导式来实现⽣成器
    3. 通过数据的转换也可以获取⽣成器

    def func():
     print("111")
     return 222
    ret = func()
    print(ret)
    结果: 
    111
    222

    将return 转换成 yield

    def func():
     print("111")
     yield 222
    ret = func()
    print(ret)
    结果: 
    <generator object func at 0x10567ff68>
    生成器的本质就是迭代器
    def func():
        print("娃哈哈")
        yield 1 # return和yield都可以返回数据
        print("呵呵呵")
    
    
    gen = func() # 不会执行你的函数. 拿到的是生成器
    
    
    # 函数中如果有yield 这个函数就是生成器函数. 生成器函数() 获取的是生成器. 这个时候不执行函数
    # yield: 相当于return 可以返回数据. 但是yield不会彻底中断函数. 分段执行函数.
    gen.__next__() #执行函数. 执行到下一个yield.
    gen.__next__()  #继续执行函数到下一个yield.
    生成器的特点和迭代器一样.取值方式和迭代器一样(__next__(), send(): 给上一个yield传值).
     1 def order():
     2     lst = []
     3     for i in range(10000):
     4         lst.append("衣服"+str(i))
     5     return lst
     6 
     7 ll = order()
     8 
     9 def order():
    10     for i in range(10000):
    11         yield "衣服"+str(i)
    12 g = order() # 获取生成器
    13 mingwei = g.__next__()
    14 print(mingwei)
    15 zhaoyining = g.__next__()
    16 print(zhaoyining)
    View Code
     1 def func():
     2     print("我是第一个段")
     3     a = yield 123
     4     print(a)
     5     print("石可心是第二段")
     6     b = yield 456
     7     print(b) # ??
     8     print("赵一宁是第三段")
     9     c = yield 789
    10     print(c)
    11     print("刘伟是最后一个段")
    12     yield 79  # 最后收尾一定是yield
    13 
    14 
    15 
    16 g = func()
    17 print(g.__next__()) # 没有上一个yield 所以不能使用send() 开头必须是__next__()
    18 print(g.send("煎饼果子"))
    19 print(g.send("韭菜盒子"))
    20 print(g.send("锅包肉"))  ## ??
    View Code
    生成器一般由生成器函数或者生成器表达式来创建
     1 def eat():
     2     print("我吃什么啊")
     3     a =  yield  "馒头"
     4     print("a=",a)
     5     b =  yield  "鸡蛋灌饼"
     6     print("b=",b)
     7     c =  yield  "韭菜盒子"
     8     print("c=",c)
     9     yield  "GAME OVER"
    10 gen = eat()      # 获取生成器
    11 
    12 ret1 = gen. __next__()
    13 print(ret1) # 馒头
    14 ret2 = gen.send("胡辣汤")
    15 print(ret2)
    16 
    17 ret3 = gen.send("狗粮")
    18 print(ret3)
    19 ret4 = gen.send( "猫粮")
    20 print(ret4)
    View Code

    二丶推导式

    1. 列表推导式 [结果 for循环 条件筛选]
    lst = []
    for i in range(1, 16):
        lst.append("python"+str(i))
    print(lst)
    
    推导式: 用一句话来生成一个列表
    lst = ["python"+str(j) for j in range(1,16)]
    print(lst)
    语法:  [结果  for循环 判断]
    View Code
    寻找名字中带有两个e的人的名字
    names = [['Tom', 'Billy', 'Jefferson' , 'Andrew' , 'Wesley' , 'Steven' ,'Joe'],
             [ 'Alice', 'Jill' , 'Ana', 'Wendy', 'Jennifer', 'Sherry' , 1]]
    
    lst = [name for line in names for name in line if type(name) == str and name.count("e") == 2]
    print(lst)
    
    # 100以内能被3整除的数的平方
    # lst = [i*i for i in range(100) if i%3==0]
    # print(lst)
    列表推导式练习

    2. 字典推导式 {k:v for循环 条件筛选}
    1 [11,22,33,44] => {0:11,1:22,2:33}
    2 lst = [11,22,33,44]
    3 dic = {i:lst[i] for i in range(len(lst)) if i < 2} # 字典推导式就一行
    4 print(dic)
    5 语法:{k:v for循环 条件筛选}
    6 
    7 dic = {"jj": "林俊杰", "jay": "周杰伦", "zs": "赵四", "ln":"刘能"}
    8 d = {v : k for k,v in dic.items()}
    9 print(d)
    View Code

    3. 集合推导式 {k for循环 条件}
     1 s = {i for i in range(100)} # 可去除重复
     2 print(s)
     3 
     4 # 集合推导式
     5 lst = [1, 1, 4, 6,7,4,2,2]
     6 s = { el for el in lst }
     7 print(s)
     8 
     9 s = set(lst)
    10 print(s)
    View Code
    三丶生成器表达式
    (结果 for循环 条件)
    特点:
    1. 惰性机制
    2. 只能向前
    3. 节省内存(鸡蛋)

    ⽣成器表达式和列表推导式的区别:
    1. 列表推导式比较耗内存. ⼀次性加载. ⽣成器表达式⼏乎不占⽤内存. 使⽤的时候才分
    配和使⽤内存
    2. 得到的值不⼀样. 列表推导式得到的是⼀个列表. ⽣成器表达式获取的是⼀个⽣成器

    def func():
      print(111)
      yield 222
    g = func() # ⽣成器g
    g1 = (i for i in g) # ⽣成器g1. 但是g1的数据来源于g
    g2 = (i for i in g1) # ⽣成器g2. 来源g1
    print(list(g)) # 获取g中的数据. 这时func()才会被执⾏. 打印111.获取到222. g
    print(list(g1)) # 获取g1中的数据. g1的数据来源是g. 但是g已经取完了. g1 也就没有数据
    print(list(g2)) # 和g1同理

    深坑==> ⽣成器. 要值得时候才拿值. 

    总结: 推导式有, 列表推导式, 字典推导式, 集合推导式, 没有元组推导式
    ⽣成器表达式: (结果 for 变量 in 可迭代对象 if 条件筛选)
    ⽣成器表达式可以直接获取到⽣成器对象. ⽣成器对象可以直接进⾏for循环.

    def add(a, b):
      return a + b
    def test():
      for r_i in range(4):
      yield r_i
    g = test() 
    for n in [2,  10]:
     g = (add(n, i) for i in g)
    print(list(g))

    惰性机制 不到最后不会拿值

      





  • 相关阅读:
    严格模式
    es6模块与 commonJS规范的区别
    Javascript内置对象、原生对象、宿主对象关系
    实现继承的几种方式
    创建对象的一些方式
    null的小扩展
    getElementById的缩略
    你真的知道为什么不推荐使用@import?
    换行与不换行
    transition与animation
  • 原文地址:https://www.cnblogs.com/xintiao-/p/9468743.html
Copyright © 2020-2023  润新知