zoukankan      html  css  js  c++  java
  • day012生成器函数、生成器表达式、列表推导式

    本节主要内容

    • 生成器和生成器表达式

    • 列表推导式

    一、生成器

    • 生成器实质就是迭代器

    1、python中获取生成器的三种方式:

    * 通过生成器函数
    * 通过生成器表达式
    * 通过数据的转换获取生成器

    1.生成器函数

    fe1:
        def func():
            print("111")
            yield 222
        ret = func()        #generator 生成器
        print(ret)  #结果:<generator object func at 0x10567ff68>
    • 函数里面有yield,就是生成器函数

      yield的作用

      ① yield + 返回值 (是一个类似 return 的关键字,迭代一次遇到yield时就返回yield后面(右边)的值。
        (生成器函数不要出现return)
      ② 重点是:下一次迭代时,从上一次迭代遇到的yield后面的代码(下一行)开始执行。(分段执行)
      ③  生成器函数被调用的时候. 返回生成器
      
        def func():
            yield
        g = func() - 得到生成器

      2.生成器的用法

      · 生成器的用法和迭代器基本一致
      ·  __next__() 开始执行生成器 .  执行到yield. 直到没有yield. 抛出StopIteration
      
      · send() 可以给上一个yield传值,send()不可以在第一个位置和最后一个位置出现

    fe:

    def func():
        print("水饺")
        a = yield "大馅水饺"
        print("a=", a)
        print("烧饼")
        b = yield "武大郎烧饼"
        print("b=",b)
        print("老婆饼")
        c = yield "只要老婆不要饼"
        print("c=", c)
    
        gen = func() # 生成器
        print("返回值是:", gen.__next__())
        print("返回值是:",gen.send("混沌面")) #  和__next__()一样也是向下找yield. 给上一个yield传值
        print("返回值是:",gen.send("胡辣汤")) #  和__next__()一样也是向下找yield. 给上一个yield传值
        print("返回值是:",gen.send("马拉")) #  和__next__()一样也是向下找yield. 给上一个yield传值
    
        send()不可以在第一个位置和最后一个位置出现
        最后的yield后的代码是可以执行的但是会报错. StopIteration

    2、生成器的三大特点(同迭代器)

     1. 省内存
     2. 惰性机制,  不访问__next__() 就没有值.
     3. 只能向前. 不能反复.

    二、各种推导式(简单)

    • 列表推导式 语法: [ 结果 for循环(可多个) if判断] 就三种,其中if可有可无

    • 字典推导式 语法: { key:value for循环 if判断}

    • 集合推导式 语法: { key for循环 if判断}

    • 切记没有元组推导式,推导式指的是可以迭代的,元组不可迭代

    fe1:

    列表推导式 快速的简单的创建一个列表
    lst = ["python全栈%s期" % i for i in range(1, 17)]
    语法: [结果 for循环 if判断]

    fe2:

    成列表: 1-20 所有的奇数的2次方
    print([ i*i for i in range(1,21) if i % 2 == 1])

    fe3:

    # [3,6,9]  已知
    # [(1,2,3), (4,5,6), (7,8,9)]
    lst = [3,6,9]
    new_lst = [(el-2, el-1, el) for el in lst]

    fe4:

    寻找名字中带有两个e的⼈的名字 name.count("e") == 2
    names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven','Joe'],
             ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
    
    lst = [name for el in names for name in el if name.count("e") == 2]
    print(lst)
    
    **此处使用到了两层for循环**

    fe5:字典中的推导式

    dic = {"张无忌":"赵敏", "杨过":"小龙女", "郭靖":"黄蓉"}
    # 把字典中的key和value互换
    # dic = {"赵敏":"张无忌", "小龙女":"杨过", "黄蓉":"郭靖"}
    dic1 = { v:k for k, v in dic.items()}  # 强化记忆,理解
    print(dic1)
    
    dic2 = { dic[k]:k for k in dic} # 强化记忆,理解
    print(dic2)

    fe6:集合中的推导式

    集合推导式 # 不可变. 不重复, 无序
    {结果 for循环 if判断}
    s = {i*"胡辣汤" for i in range(10)}
    print(s)

    三、生成器表达式

    • 生成器表达式 (结果 for循环 if判断) => 生成器表达式

    1、特点: 本质是迭代器. next()

    1. 省内存
    2. 惰性机制
    **生成器只有在访问时才取值,你找他要,他才给你值,
    不找是不会执行的,面试题就喜欢出这里,**
    3. 只能向前

    2、实例

    1、惰性机制的体现

    fe1:
    **list内置了for循环**
    g = (i for i in range(10))
    #* s = {1,2 , 3, 4, 5} => list(s) => list = [1,2,3,4,5,]
    #上面的转换说明了list里面存在,for循环
    print(list(g)) # 把传递进来的数据转化成列表.  里面包含了for循环
    # list() => for=> __iter__() ==> __next__()
    
    print(list(g)) # 上一次已经拿没了
    print(g.__next__()) # 已经没有数据了
    for el in g:
        print(el)
    for el in g: # 已经没有数据了 惰性机制-> 只能往前
        print(el)
    fe2:重要的面试题
    def func(): # 生成器函数
        print(111)
        yield 222
    
    g = func() #  生成器 -> 没有执行过__next__()
    g1 = (i for i in g) # 生成器表达式. 也没有__Next__()
    g2 = (i for i in g1) # 生成器表达式. 也没有__Next__()
        #到此为止, 没有人拿过值
    
        **需要知道的知识点:list里内置了for循环**
    
    print(list(g2)) # 111 [222] #
    print(list(g)) #  []
    print(list(g1)) # []
    
        **关键点:生成器表达式,一旦被拿完了,就没有了,直白说,一旦被人拿了,就没了。**

    3、yield from

    ⼩坑

    yield from是将列表中的每⼀个元素返回. 所以.
    如果写两个yield from 并不会产⽣交替的效果

    fe1:

    def gen():
        lst = ["⿇花藤", "胡辣汤", "微星牌饼铛", "Mac牌锅铲"]
        yield from lst # 把列表中的每一个元素返回
        # yield  lst[0] # 等同于下面四个命令的组合
        # yield  lst[1]
        # yield  lst[2]
        # yield  lst[3]
    
    g = gen() # 生成器函数 -> 获取生成器
    for el in g:

    fe2:

    def gen():
        lst = ["⿇花藤", "胡辣汤", "微星牌饼铛", "Mac牌锅铲"]
        lst2 = ["饼铛还是微星的好", "联想不能煮鸡蛋", "微星就可以", "还可以烙饼"]
        yield from lst  # 先循环打印lst,再打印lst2
        # yield lst[0]
        # yield lst[1]
        # yield lst[2]
        # yield lst[3]
        yield from lst2
        # yield lst2[0]
        # yield lst2[1]
        # yield lst2[2]
        # yield lst2[3]
    
    g = gen() # 获取生成器
    for el in g: # 从生成器获取数据
        print(el) # 打印
  • 相关阅读:
    HDU多校第六场——HDU6638 Snowy Smile(线段树区间合并)
    java
    java
    java
    java
    java
    python
    appium
    python
    python
  • 原文地址:https://www.cnblogs.com/yipianshuying/p/9891373.html
Copyright © 2011-2022 走看看