一.昨日内容回顾
  惰性机制(只有执行__next__()才会取值)
二.今日主要内容
    1.生成器
        生成器:本质是迭代器,写法和迭代器不一样.用法和迭代器一样.
        ※生成器记录的是代码
    2.生成器函数
        生成器函数: 在函数中return换成yield. 这个函数就是生成器函数
        def func():
            yield
     yield from iterable  相当于 for el in iterable: yield el
       取值:
            gen.__next__() 下一个
            gen.send()  可以给上一个yield传值,第一次执行不能用send(),不能给最后一个yield传值
        gen = func() 函数并不会被执行,而是创建一个生成器对象
        def func()
            print('你好啊,我叫赛利亚.')
            yield '西岚的武士刀'  #return 和yield都可以返回数据
        ret = func()   #generator   ret是一个生成器
        print(ret)
        s = ret.__next__()
        print(s)
     yield from:
      
![]()
def func():
    lst = ["三国演义", "红楼梦", "北国的雪", "了不起的盖茨比"]
    # for el in lst:
    #     yield el
    yield from lst
gen = func()
print(gen.__next__())
print(gen.__next__())
print(gen.__next__())
print(gen.__next__())
 
View Code 
 
def func():
    lst = ["三国演义", "红楼梦", "北国的雪", "了不起的盖茨比"]
    # for el in lst:
    #     yield el
    yield from lst
 
View Code
 
 
        -------------生成器取值-------------------------
        def func():
            print(111)
            yield 222
        g = func() #  生成器
        g1 = (i for i in g) # 生成器
        g2 = (i for i in g1) # 生成器
        # print(list(g))  # 才会开始真正的取数据
        print(list(g1)) # 222
        print(list(g2))
        print(list(g))
        --------------------------------------
        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("胡辣汤")    # a胡辣汤'赋值给a
        print(ret2)
        ret3 = gen.send("狗粮")
        print(ret3)
        ret4 = gen.send("猫粮")
        print(ret4)
        --------------------------------------
        库存10000件衣服,每次领用1件
        def func():
            for i in range(10000):
                yield '衣服%s' % i
        gen = func()      #生成器   注意:生成器不能直接替换到下面yf中,否则会生成新的生成器
        yf1 = gen.__next__()
        yf2 = gen.__next__()
        yf3 = gen.next__()
        -----------------一次拿50个---------------------
        def func():
            lst = []
            for i in range(1, 10000):
                lst.append('衣服%s' % i)
                if i % 50 == 0:
                    yield lst
                    lst = []
        gen = func()
        print(gen.__next__())
        print(gen.__next__())
        -----------------send()---------------------
        def func():
            print('韭菜盒子')
            a = yield '娃哈哈'
            print('肉包子', a)
            b = yield '脉动'
            print('锅包肉', b)
            yield '冰红茶'
            gen = func()
            ret = gen.__next__()
            print(ret)
            # ret = gen.__next__()
            # print(ret)
            ret = gen.send('大熊猫')  #给上一个yield传值
            print(ret)
            ret = gen.send('长颈鹿')  #给上一个yield传值
            print(ret)
        --------------------------------------
        # 计算两个数的和
        def add(a, b):
            return a + b
        # 生成器函数, 0-3
        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)  # 循环的内部也是一个生成器 # 生成器记录的是代码
        #  __next__()
        # list()
        print(list(g)) # 刚开始拿数据
        --------------------------------------
        --------------------------------------
        def func():
            print('拿出手机')
            print('打开陌陌')
            yield '手机'
            print('搜索附近的人')
            print('找到小姐姐')
            yield '电脑'
            print('我是最后一行')
        gen = func()
        print(gen.__next__())    #打印到第一个yield
        print(gen.__next__())    #从上一次打印结束的位置开始打印到第二个yield, yield起到分段作用
        print(gen.__next__())  #报错. 打印完最后一行后找不到yield,所以提示StopIteration.
    3.各种推导式
        1.列表推导式:[结果 for循环 if条件]
        2.字典推导式:{key: value for循环 if条件}
        3.集合推导式: {key for循环 if条件}
        列表推导式:
        lst = ['python%s期' % i for i in range(1, 17)]
        print(lst)
         --------------------------------------
        # 创建列表
        # for i in range(1,100,2):
        lst = [i for i in range(1, 100, 2)]
        print(lst)
        lst = [i for i in range(1, 100) if i % 2 == 1]
        print(lst)
        在列表中装入python1期到python16期
        lst = []
        for i in range(1, 17):
            lst.append('python%s期'i)
        print(lst)
        --------------------------------------
        寻找名字中带有2个e的名字
        names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven','Joe'],
         ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
        lst = [el2 for el in names for el2 in el if el2.count('e') >= 2]
        print(lst)
        字典推导式
        dic = {'张无忌': '九阳神功', '周芷若': '九阴真经', '楚留香': '帅'}
        d = {dic[k]: k for k in dic}
        print(d)
        lst1 = ['东北', '陕西']
        lst2 = ['大拉皮儿', '油泼面']
        dic = {lst1[i]: lst2[i] for i in range(len(lst1))}
        print(dic)
        集合推导式
        {key for if}
        lst = [1, 1, 2, 2, 3, 3, 45]
        s = {el for el in lst}
        print(s)
    4.生成器表达式(笔试题)
        (结果 for循环 if条件)
        可以使用生成器表达式直接创建生成器
        gen = (i for i in range(10))  #generator
        print(gen.__next__())
        print(gen.__next__())
        生成器表达式:记录一下代码.然后每次需要的时候去生成器中执行一次这个代码
        列表推导式: 一次性把所有的数据创建出来,容易产生内存浪费
        特点:
            1.节省内存
            2.惰性机制   ※
            3.只能向前