zoukankan      html  css  js  c++  java
  • python3.6入门到高阶(全栈) day012 生成器

    今日主要内容(重要)
    迭代器
    __iter__() 获取迭代器
    __next__() 下一个

    生成器
    本质就是迭代器
    两种方式写生成器
    1. 生成器函数
    2. 生成器表达式

    生成器函数
    函数内部有yield. yield返回 -> return
    yield可以把函数分段执行
    生成器函数被调用的时候. 返回生成器
    def func():
    yield
    g = func() - 得到生成器
    def func():
    print("111")
    yield 222
    gener = func() # 这个时候函数不会执⾏. ⽽是获取到⽣成器
    ret = gener.__next__() # 这个时候函数才会执⾏. yield的作⽤和return⼀样. 也是返回
    数据
    print(ret)
    结果:
    111
    222
    # 那么我们可以看到, yield和return的效果是⼀样的. 有什么区别呢?
    yield是分段来执一个函数. return呢? 直接停止执行函数.

    生成器的用法和迭代器基本一致
    __next__() 开始执行生成器 . 执行到yield. 直到没有yield.
    抛出StopIteration

    send() 可以给上一个yield传值
    def eat():
    print("我吃什么啊")
    a = yield "馒头"
    print("a=",a)
    b = yield "⼤饼"
    print("b=",b)
    c = yield "⾲菜盒⼦"
    print("c=",c)
    yield "GAME OVER"
    gen = eat() # 获取⽣成器
    ret1 = gen.__next__()
    print(ret1)
    ret2 = gen.send("胡辣汤")
    print(ret2)
    ret3 = gen.send("狗粮")
    print(ret3)
    ret4 = gen.send("猫粮")
    print(ret4)
    send和__next__()区别:
    1. send和next()都是让⽣成器向下走⼀次
    2. send可以给上一个yield的位置传递值, 不能给最后一个yield发送值.
    在第一次执行生成器代码的时候不能使用send()

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


    各种推导式(简单)
    列表推导式 [ 结果 for 变量 in 可迭代对象 if 条件]
    lst =[]
    for i in range(1,18)
    lst.append(i)
    print(lst)
    替换成列表推到式
    lst =[i for i in range(1,18)]
    print(lst)

    例 # [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]

    # for el in lst: # 3
    # new_lst.append((el-2, el-1, el))
    # print(new_lst)

    例 # 寻找名字中带有两个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)

    字典推导式 {key: value for循环 if判断}
    例 # lst = [11, 22, 33] # => {0:11, 1:22, 2:33}
    # dic = {i:lst[i] for i in range(len(lst)) }
    # print(dic)

    例 # 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)

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

    生成器表达式(最难)
    (结果 for循环 if判断)
    惰性机制, 不访问__next__() 就没有值.
    只能向前. 不能反复.

    例 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同理
    ### list 具有 __next__ 效果
    for循环的机制
    for i in [1,2,3]:
    print(i)
    使⽤while循环+迭代器来模拟for循环
    lst = [1,2,3]
    lst_iter = lst.__iter__()
    while True:
    try:
    i = lst_iter.__next__()
    print(i)
    except StopIteration:
    break
    ###

    yield from

    例 def gen():
    lst = ["⿇花藤", "胡辣汤", "微星牌饼铛", "Mac牌锅铲"]
    lst2 = ["饼铛还是微星的好", "联想不能煮鸡蛋", "微星就可以", "还可以烙饼"]
    yield from lst
    yield from lst2
    g = gen()
    for el in g:
    print(el)
    效果:
    麻花藤
    胡辣汤
    微星牌饼铛
    Mac牌锅铲
    饼铛还是微星的好
    联想不能煮鸡蛋
    微星就可以
    还可以烙饼
  • 相关阅读:
    leetcode@ [300] Longest Increasing Subsequence (记忆化搜索)
    leetcode@ [200] Number of Islands
    JMETER压力测试报错:JAVA.NET.BINDEXCEPTION: ADDRESS ALREADY IN USE: CONNECT
    压力测试报告模版
    Jmeter学习—004—使用代理录制脚本—HTTP代理服务器(APP、web皆可)
    怎么用fiddler抓APP的包
    Jmeter录制脚本过程及Could not create script recorder报错、您的连接不是私密连接报错
    Github使用说明 --整理者米米
    Anaconda详细安装使用教程
    运用MQTT-JMeter插件测试MQTT服务器性能
  • 原文地址:https://www.cnblogs.com/wanxiangai/p/9891081.html
Copyright © 2011-2022 走看看