zoukankan      html  css  js  c++  java
  • 四. python进阶(生成器,生成函数 )

    """def ret():
        return  111
    print(ret())   # 111
    """
    
    """
    def ret():
        yield 111
    print(ret())   # <generator object ret at 0x000001A5A195FF68>   返回一个生成器
    """
    
    """def ret():
        yield 111
        print(222)
    aa=ret()  #  不会执行你的函数  拿到的生成器
    bb=aa.__next__()  # 会执行到一个yield
    print(bb)
    
    cc=aa.__next__()
    print(cc)   #  StopIteration
    """
    
    # 函数中有yiled 这就是一个生成器函数     获取的是生成器  这个时候不执行函数    一个惰性机制
    # yield  相当于 return  可以返回数据  但是yiled 不会彻底中断函数 分段执行函数
    
    # gen.__next__()执行函数 执行下一个yiled
    # gen.__next__() 继续执行下一个yield
    # 一个惰性机制  只能向下走    省内存
    
    """
    def coder():
          for i in range(55):
             yield  "衣服"+str(i)
    gen=coder()  # 获取到生成器
    
    # aa=gen.__next__()
    # print(aa)
    
    # bb=gen.__next__()
    # print(bb)
    
    cc=0
    for i in gen:
        cc+=1
        if cc>6:
            break
        print(i)
    """
    
    # send
    # send()和 __next__()是一样 可以执行yiled 可以给上一个yiled传值
    def func():
        print("111111")
        yield 1
        print("222222")
        yield 2
        print("333333")
        yield 3
        print("444444")
        # yield 0    最后收尾一定是yiled    不然会报错   # StopIteration
    g=func()
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    # print(g.__next__())  # StopIteration
    
    print("**************************************send************************************")
    print("**************************************************************************")
    
    """def func():
        print("111111")
        a=yield 1
        print(a)
    
        print("222222")
        b=yield 2
        print(b)
    
        print("333333")
        c=yield 3
        print(c)
    
        print("444444")
        d=yield 66666
    
    g=func()
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    #
    # 111111
    # 1
    # None
    # 222222
    # 2
    # None
    # 333333
    # 3
    # None
    # 444444
    # 66666
    """
    
    def func():
        print("111111")
        a=yield 1
        print(a)
        print("222222")
        b=yield 2
        print(b)
        print("333333")
        c=yield 3
        print(c)
        print("444444")
        yield 999999999999    # 注意最后一个 yiled 是不能传值的 不然会报错
    
    
    g=func()
    print(g.__next__())   # 第一次必须是__next__()  就是开头必须是__next__()
    print(g.send("哈哈哈哈哈"))
    print(g.send("啦啦啦啦啦"))
    print(g.send("叽叽叽叽"))
    #
    # 111111
    # 1
    # 哈哈哈哈哈
    # 222222
    # 2
    # 啦啦啦啦啦
    # 333333
    # 3
    # 叽叽叽叽
    # 444444
    # 999999999999

    一 .生成器

    理解生成器 函数
    只有含有yield的关键字都是生成器函数 但是不能和return共用 注意 yield只能在函数内部使用
    生成器 本质就是迭代器
    用到 处理很多数据时应用 yield 一条一条的返回数据
    def aa():
        print(1)
        yield "a"
        # 生成器函数:执行之后会得到一个生成器作为返回值
    cc=aa()
    
    print(cc)        #  <generator object aa at 0x00000259830C2EB8> 生成器
    print(cc.__next__()) # 1    a
    def aa():
        print(1)
        yield "a"
        print(2)
        yield "b"
        yield "c"
    cc=aa()
    g=cc.__next__()
    print(g)  #  1   a
    
    g=cc.__next__()
    print(g)  # 2    b
    
    
    g=cc.__next__()
    print(g) # c
    def aa():
        print(1)
        yield "a"
        print(2)
        yield "b"
        yield "c"
    c=aa()
    for i in c:
       print(i)
    def dd():
        for i in range(5):
            yield "生成50个哇哈哈%s"%i
    a=dd()
    for i in a:
        print(i)
    
    print("*************************************")
    def dd():
        for i in range(21):
            yield "生成50个哇哈哈%s"%i
    a=dd()
    dd=0
    for i in a:
        dd+=1
        print(i)
        if dd>6:
            break
    print("*************************************")
    
    
    # 表示生成了两个迭代器      而生成器函数可以作用于一个迭代器
    ll=[1,2,3,4,5,6]
    for i in ll:
        if i==3:
            break
        print(i)
    
    print("*************************************")
    for i in ll:
        print(i)
    def ff():
        for i in range(100):
             yield "生成%s"%i
    f=ff()
    f1=ff()
    print(f.__next__())
    print(f.__next__())
    print(f.__next__())
    print(f.__next__())
    print(f.__next__())
    print("***********")
    print(f1.__next__())
    print(f1.__next__())
    # 说明了自己走自己的   相当于两个迭代器
    # 生成0
    # 生成1
    # 生成2
    # 生成3
    # 生成4
    # ***********
    # 生成0
    # 生成1
    def aa():
       print(1)
       yield "a"
    dd=aa()
    # print(list(dd))   数据类型强制转换 也可以取值 但是太占内存了
    print(dd)
    # 生成器函数 :执行之后会得到一个生成器作为返回值
    # generator  生成器
    print(dd.__next__())
    
    # <generator object aa at 0x000001CF75392EB8>
    # 1
    # a
    def bb():
        print("aaaaa")
        yield "我是aaaa"
        print("bbbbb")
        yield "我是bbbb"
        yield "我是ccc"
    print(bb())
    cc=bb()
    print(cc)
    print(cc.__next__())
    # aaaaa
    # 我是aaaa
    
    print(cc.__next__())
    # bbbbb
    # 我是bbbb
    def bb():
        print("aaaaa")
        yield "我是aaaa"
        print("bbbbb")
        yield "我是bbbb"
        yield "我是ccc"
    
    cc=bb()
    # print(cc.__next__())   # aaaaa  我是aaaa
    # print(cc.__next__())  # bbbbb   我是bbbb
    # print(cc.__next__())  # 我是ccc
    print("**************************************")
    
    print(cc,"这是迭代器哈哈哈哈哈")
    for i in cc:
         print(i,"for循环")
    # aaaaa
    # 我是aaaa for循环
    
    # bbbbb
    # 我是bbbb for循环
    
    # 我是ccc for循环
    # 边生成数据边处理数据
    def ff():
        for i in range(100):
             yield "生成%s"%i
    f=ff()
    for i in f:
        print(i)
    
    
    # 边生成数据边处理数据
    def ff():
        for i in range(100):
             yield "生成%s"%i
    f=ff()
    cont=0
    for i in f:
        cont+=1
        if cont>50:
            break
        print(i)
    def aa():
        print(111)
        yield "我是111"
        print(222)
        yield "我是222"
        yield "我是垃圾"
    b=aa()
    # print(b)
    print(b.__next__())  # 111    我是111
    print(b.__next__())  # 222  我是222
    print(b.__next__())  # 我是垃圾

    1. send方法() 以在获取下一个值时 可以给上一个yield的位置传递参数

    def aa():
        print(111)
        yield "我是111"
        print(222)
        yield "我是222"
        yield "我是垃圾"
    b=aa()
    # print(b)
    print(b.__next__())    # 111  我是111
    print(b.send(None))    # send的效果和next一样   # 222  我是222
    # send获取下一个值的效果和next一样的
    # 但是send 可以在获取下一个值时 可以给上一个yield的位置传递参数
    # send 注意使用
    #      第一次使用生成器的时候 是必须用next获取下一个值
    #      最后一个yield不能接受外部的值
    def aa():
        print(111)
        cont=yield "我是111"
        print("我是",cont)
        print(22222)
        yield "我是333333"
    b=aa()
    # print(b)
    print(b.__next__())
    # 111
    # 我是111
    print(b.send("hello"))   #  send的效果和next一样   但是可以传参数
    # 我是 hello
    # 22222
    # 我是333333
    # 获取移动平均值
    # 10 20 30 10
    # # avg=sum/count
    def bb():
        sum=0
        count=0
        avg=0
        while True:
            num=yield avg
            sum+=num
            count+=1
            avg=sum/count
    
    c=bb()
    c.__next__()
    av=c.send(20)
    av=c.send(30)
    av=c.send(10)
    print(av)
    生成器 获取平均值案例

     2. yield from

    def gen():
        a='123456'
        b='abcdef'
    
        yield from a
        yield from b
    
    a=gen()
    for i in a:
        print(i)
    # 监听文件用户文件输入
    aa=r"D:aaaa育1day生成器函数aa.txt"
    # strip() 方法用于移除字符串头尾指定的字符
    def cc(bb):
      with open(bb,encoding="utf-8")as f1:
       while True:
           li=f1.readline()
           if li.strip(): #去掉回车空格
               yield  li.strip()
    dd=cc(aa)
    
    for i in dd:
        print("****",i)
    生成器函数文件监听案例
    def bb():
        for i in range(20):
            yield "生成%d"%i
    
    aa=bb()
    cc=0
    for i in aa:
        cc+=1
        if cc>6:
            break
        print(i)
    # 生成0
    # 生成1
    # 生成2
    # 生成3
    # 生成4
    # 生成5
    # with open('25生成器人口普查','r',encoding='utf-8') as f:
    
    # 利用生成器取人口数
    
    def g():
        
        with open('./25生成器人口普查.py','r',encoding='utf-8') as f:
            for i in f:
               yield i
    a=g()
    c1=a.__next__()
    c2=a.__next__()
    print(c1)
    print(c2)
    
    # {"name":"上海","renkou":7700}
    # {"name":"湖北","renkou":1400}
    
    print("*******************# 利用生成器取人口数***************************")
    
    
    
    
    def A():
        with open('./25生成器人口普查.py','r',encoding='utf-8') as f:
            for i in f:
               yield i
    S=A()
    k=eval(S.__next__())  # 转换成字典dict
    print(k)
    print(type(k))  
    # {'name': '上海', 'renkou': 7700}
    # <class 'dict'>
    print(k['renkou'])   
    # 7700
    
    
    
    # 取出所以人口数
    def Q():
        with open('./25生成器人口普查.py','r',encoding='utf-8') as f:
            for i in f:
               yield i
    n=Q()
    for h in n:
        D=eval(h)
        print(D['renkou'])
    # 7700
    # 7700
    # 1400
    # 500
    # 600
    # 30000
    # 222200
    
    print("*********************1111****************************")
    
    # 求出总人数
    def ff():
        with open('./25生成器人口普查.py','r',encoding='utf-8') as f:
            for i in f:
               yield i
    v=ff()
    res=0
    for h in v:
        D=eval(h)
        # print(D['renkou'])
        res+=D['renkou']
    print(res)    # 262400
    
    
    
    # 求出总人数
    def ff():
        with open('./25生成器人口普查.py','r',encoding='utf-8') as f:
            for i in f:
               yield i
    v=ff()
    
    x=sum(eval(i)['renkou'] for i in v)
    print(x)
    
    
    # 描述
    # sum() 方法对系列进行求和计算。
    
    # 语法
    # 以下是 sum() 方法的语法:
    
    # sum(iterable[, start])
    # 参数
    # iterable -- 可迭代对象,如:列表、元组、集合。
    # start -- 指定相加的参数,如果没有设置这个值,默认为0。
    # 模拟生产包子吃包子
    
    # 注意:这样生产消费太消耗时间了 不严谨
    # 01 生产包子
    def aa ():
     ret=[]
     for x in range(20):
         ret.append('包子%s'%x)
     return ret
    
    # 02 造人来一个吃一个
    def bb(res):
      for index,baozi in enumerate(res):
       print('第%s个人,吃了%s'%(index,baozi))
    res=aa()
    bb(res)
    """第0个人,吃了包子0
    第1个人,吃了包子1
    第2个人,吃了包子2
    第3个人,吃了包子3
    第4个人,吃了包子4
    第5个人,吃了包子5
    ........"""
    # 母鸡下载案例   (生成器)
    
    # 这种案例 :生成器   占空间大  效率低
    # 
    # 这个表示鸡蛋全部下出来了
    def xiadan():
         ret=[]
         for i in range(8):
            ret.append('鸡蛋%s'%i)
         return  ret
    aa=xiadan()
    
    print(aa)
    # ['鸡蛋0', '鸡蛋1', '鸡蛋2', '鸡蛋3', '鸡蛋4', '鸡蛋5', '鸡蛋6', '鸡蛋7']
    
    
    # 这个表示需要一个鸡蛋就下一个
    def vv():
       for i in range (8):
           yield '鸡蛋%s'%i
    aa=vv()
    BB1=aa.__next__()
    BB2=aa.__next__()
    BB3=aa.__next__()
    
    print(BB1)     # 鸡蛋0
    print(BB2)     # 鸡蛋1
    print(BB3)     # 鸡蛋2
    # 列表解析
    aa=[]
    for a in range(6):
        aa.append("张三%s"%a)
    print(aa)
    # ['张三0', '张三1', '张三2', '张三3', '张三4', '张三5']
    
    # 生成器表达式
    
    c=["李四%s"%i for i in range(6)]
    print(c)
    
    # ['李四0', '李四1', '李四2', '李四3', '李四4', '李四5']
    
    
    D=["李四%s"%i for i in range(10) if i>5]
    print(D) 
    # ['李四6', '李四7', '李四8', '李四9']
    
    # 生成器表达式
    tt=("张飞%s"%i for i in range(10))
    print(tt)
    print(tt.__next__())
    print(tt.__next__())
    print(next(tt))
    print(next(tt))
    print(next(tt))
    # <generator object <genexpr> at 0x000002902A550D00>
    # 张飞0
    # 张飞1
    # 张飞2
    # 张飞3
    # 张飞4
    # 模拟生产包子吃包子
    
    # 注意:这样生产消费太消耗时间了 不严谨
    # 01 生产包子
    def aa ():
     ret=[]
     for x in range(20):
         ret.append('包子%s'%x)
     return ret
    
    # 02 造人来一个吃一个
    def bb(res):
      for index,baozi in enumerate(res):
       print('第%s个人,吃了%s'%(index,baozi))
    res=aa()
    bb(res)
    """第0个人,吃了包子0
    第1个人,吃了包子1
    第2个人,吃了包子2
    第3个人,吃了包子3
    第4个人,吃了包子4
    第5个人,吃了包子5
    ........"""
    def aa():
        print('开始了')
        yield 1
        print('第一次')
        yield 2
        print('第二次')
    bb=aa()
    res1=bb.__next__()
    print(res1)
    # 开始了
    # 1
    
    res2=bb.__next__()
    # print(res2)
    # 第一次
    # 2
    3.xrange和range 区别
    # xrange 不会生成值  只有用的时候才会生成
    # range  会直接生成一个列表 值已经生成
    for a in range(1,5):
    
        print(a)
    # 0
    # 1
    # 2
    # 3
    # 4
    
    
    
     
    
    
  • 相关阅读:
    WEB前端第四十四课——jQuery框架(二)常用方法
    WEB前端第四十三课——jQuery框架(一)$()函数、添加事件监听
    WEB前端第四十二课——应用案例-瀑布流、递归、代理
    WEB前端第四十一课——简单算法与解析indexof、hash、冒泡排序、递归、JSON
    WEB前端第四十课——正则表达式-RegExp、高级
    WEB前端第三十九课——HTML正则表达式-基础、修饰符、检索模式
    SITE STRUCTURE
    CSS GRID ESSENTIALS
    CSS TYPOGRAPHY
    CSS COLOR
  • 原文地址:https://www.cnblogs.com/Sup-to/p/10849140.html
Copyright © 2011-2022 走看看