zoukankan      html  css  js  c++  java
  • 12_python_生成器

    一、生成器

     

      python中有三种方式获取生成器
      (1)通过生成器函数
      (2)通过各种推导式来实现生成器
      (3)通过数据的转换也可以获取生成器
     
      1、只要函数中存在了yield,那么这个函数就是一个生成器函数,生成器实质就是迭代器,所以生成器可以直接执行__next__()
     1 def func():
     2  print("111")
     3  yield 222
     4 gener = func() # 这个时候函数不会执行. 而是获取到⽣成器
     5 ret = gener.__next__() # 这个时候函数才会执行. yield的作用和return一样. 也是返回数据
     6 ret = gener.__next__() # 报错StopIteration
     7 print(ret)
     8 结果:
     9 111
    10 222
      yield是分段来执⾏⼀个 函数. return呢? 直接停⽌执⾏函数。种使⽤⽣成器. ⼀次就⼀个. ⽤多少⽣成多少. ⽣成器是⼀个⼀个的指向下⼀个. 不会回去, __next__()到哪, 指针就指到哪⼉. 下⼀次继续获取指针指向的值. 
     
      2、send()
      send和__next__()⼀样都可以让⽣成器执⾏到下⼀个yield. 
     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 ret1 = gen.__next__()
    12 print(ret1)
    13 ret2 = gen.send("胡辣汤") # 给上一个yield传值,也就是a
    14 print(ret2)
    15 ret3 = gen.send("狗粮")
    16 print(ret3)
    17 ret4 = gen.send("猫粮")
    18 print(ret4)
    19 结果:
    20 我吃什么啊
    21 馒头
    22 a= 胡辣汤
    23 烧饼
    24 b= 狗粮
    25 菜盒子
    26 c= 猫粮
    27 GAME OVER
      3、send和__next__()区别: 
          (1). send和next()都是让⽣成器向下走⼀次 
          (2). send可以给上⼀个yield的位置传递值, 不能给最后⼀个yield发送值. 在第⼀次执⾏⽣成器代码的时候不能使⽤send()
     
      4、⽣成器可以使⽤for循环来循环获取内部的元素:
     1 def func():
     2     print(111)
     3     yield 222
     4     print(333)
     5     yield 444
     6     print(555)
     7     yield 666
     8 gen = func()
     9 for i in gen:
    10     print(i)
    11 结果:
    12 111
    13 222
    14 333
    15 444
    16 555
    17 666

      执行生成器的方式:

     1 第一种
     2 def func()
     3     print('hello')
     4     yield 111
     5 gen = func()
     6 for i in gen:
     7     print(i)
     8 第二种
     9 lst = list(gen)
    10 print(lst)
    11 第三种
    12 gen.__next__()

    二、推导式

      1、列表推导
         [ 结果 for 变量 in 可迭代对象 if 条件 ]
    1 # 100以内能被3整除的数的平方
    2 gen = (i * i for i in range(100) if i % 3 == 0)
    3 for num in gen:
    4  print(num)
      2、字典推导式
        {key: value for循环 if 筛选}
    1 # dic = {"张无忌":"九阳神功", "乔峰":"降龙十八掌", "楚留香":"帅"}
    2 # d = {dic[k]: k for k in dic}
    3 # print(d)
      3、集合推导式
         {key for if}
    1 # lst = ["周杰伦","周伯通","周润发","周伯通","周笔畅","周伯通","周星驰","周伯通"]
    2 # s = {el for el in lst}
    3 # print(s)

      ⽣成器表达式和列表推导式的区别:

        1. 列表推导式比较耗内存. ⼀次性加载. ⽣成器表达式⼏乎不占⽤内存. 使⽤的时候才分 配和使⽤内存

        2. 得到的值不⼀样. 列表推导式得到的是⼀个列表. ⽣成器表达式获取的是⼀个⽣成器.⽣成器的惰性机制: ⽣成器只有在访问的时候才取值

  • 相关阅读:
    62 ip与int类型的转换
    60再谈指针
    59任由制转换
    58进制转换工具
    吉哥工作
    apple
    找第一个非0元素的位置
    若干个数据之和 不考虑溢出
    汇编程序w=x*y+z-200
    4位bcd数转换为2进制数
  • 原文地址:https://www.cnblogs.com/hq82/p/9670332.html
Copyright © 2011-2022 走看看