• day14 生成器/ 表达式形式yield的应用/三元表达式与列表推导式/字典生成式/杂项


    生成器:函数内包含有yield的关键字,再调用函数,就不会执行函数体代码,拿到的返回值就是一个生成器对象

    def chicken():
    print('first======>')
    yield 1
    print('second======>')
    yield 2
    print('third======>')
    yield 3

    res=chicken()
    #生成器本质就是迭代器,也就是说生成器的玩法,就是迭代器的玩法
    # print(res) #得到一个生成器对象
    res.__next__() #first======>
    res.__next__() #second=====>
    res.__next__() #third======>

    得到返回值

    def chicken():
        print('first======>')
        yield 1
        print('second======>')
        yield 2
        print('third======>')
        yield 3
    
    obj=chicken()
    
    res=obj.__next__()                    
    print(res)                            
    res=obj.__next__()                    
    print(res)             
    res=obj.__next__()     #每次next取的是yield后面的值               
    print(res)
    
    # first======>    #next就能取值,取的是函数的返回值
    # 1
    # second======>  下一次next基于上一次暂停的位置往下走
    # 2
    # third======>
    # 3
    

    for循环的迭代原理

    # for循环原理
    def chicken():
        print('========>first')
        yield   1
        print('========>second')
        yield   2
        print('========>third')
        yield   3
    obj=chicken()
    #1、iter_obj=obj.__iter__(),拿到迭代器
    #2、触发iter_obj.__next__(),拿到该方法的返回值,赋值给 item
    #3、周而复始,直到函数内不再有yield,即取值完毕
    #4、for会检测到StopIteration结束循环 for item in obj:#obj是可迭代对象 obj.__iter__() print(item)

    总结yield:

    #1、为我们提供了一种自定义迭代器的方式

    #2、可以在函数内用yield的关键字,调用函数拿到的结果就是一个生成器,生成器就是迭代器,yield可以像return一样用于返回值,区别return只能返回一次值

    而yield 可以返回多次值   yield可以保存函数的执行状态

    def my_range():
        print('start....')
        n=0
        while True:
            yield n
            n+=1
    obj=my_range()
    print(obj)  #生存器的内存地址
    
    print(obj.__next__())
    print(obj.__next__())
    print(obj.__next__())
    
    def my_range(start,stop,step):
        n=start
        while n<stop:
            yield n
            n+=step
    
    obj=my_range(3,7,2)
    print(obj.__next__())
    print(obj.__next__())

    for item in my_range(5,10,2)
      print(item)

     表达式形式yield的应用

    def eat(name):
        print('%s ready to eat'%name)
        food_list=[]
        while True:
            print('我草靠日')
            food=yield food_list#food='骨头
            food_list.append(food)#food='泔水',循环一次停在yield
            print('%s start to eat%s'%(name,food))
    
    dog1=eat('alex')
    
    #1、 必须初始化一次,让函数停在yield的位置
    dog1.__next__()
    
    #2、接下来的事,就是喂狗
    #send有两方面的功能
    # 1、给yield传值
    # 2、同__next__的功能
    res1=dog1.send('泔水')#传值 #传多个值要放能存多个值的数据类型里面
    print(res1)
    res2=dog1.send('骨头')
    print(res2)
    res3=dog1.send('shit')
    print(res3)
    

    三元表达式与列表推导式

    三元表达式
    条件成立时的返回值 if 条件else不成立的返回值

    def max(x,y):
        if x> y:
            return x
        else:
            return y
    x=10
    y=20
    
    res=x if x>y else y
    print(res)
    

    三元哪三元呢 中间x>y条件算一元 条件成立的返回值算一元(x) 右边条件成立的返回值算一元(y)

    #列表生成式

    l=[]

    for i in range(1,11)

    names=['alex','wxx','lxx']
    l=[]
    for name in names:
        l.append(name+'SB')
    print(l)
    
    # 可以简写成
    names=[name+'SB' for name in names]
    print(names)
    

    列表生成式子

    l=[item**2 for item in range(1,11)]
    print(l)
    names=['alex','wxx','egon','lxx','zhangmingyan']
    # l=[]
    # for name in names:
    #     if name != 'egon':
    #         l.append(name + 'SB')
    # names=l
    names=[name+'SB' for name in names if name != 'egon'] #列表式可以这么表示
    print(names)  
    

    语法:[expression for iteml in iterable1 if conditionl]

    列表生成式的目的是更方便的造列表

    列表生成式只能for if ......for if 不能跟else

    错误:l=[item**2 for item in range(1,5) if item>2 else]

    字典生成式

    s1='hello'
    l1=[1,2,3,4,5]
    res=zip(s1,l1)
    # print(res)  #<zip object at 0x00000000021BBEC8>
    print(list(res))#[('h', 1), ('e', 2), ('l', 3), ('l', 4), ('o', 5)]
    
    keys=['name','age','sex']
    values=['egon',18,'male']
    res=zip(keys,values)
    print(res)
    print(list(res))
    print(list(res))  #这里迭代器为什么只可以取值一次
    d={}
    for k,v in res:
        d[k]=v
    print(d)
    
    info={'name':'egon','age':18,'sex':'male'}
    
    keys=info.keys()
    print(keys)
    values=info.values()
    print(values)
    
    
    
    
    再把keys和values转回原来的字典
    d={k:v for k,v in zip(keys,values)}
    print(d)
    

    杂项

    t=(i for i in rang(10))
    print(t)   #花括号字典,中括号列表 小括号不是元祖
    
    #<generator object <genexpr> at 0x00000000020CFCA8>
    

    生成器好处省内存

    生成器表达式
    g=(i for i in range(10))
    # print(g)
    
    print(next(g))
    print(next(g))
    
    with open('a.txt',encoding='utf-8') as f:      #生成器表达式
        nums=[len(line) for line in f]             # g=(i for i in range(10))
        # nums=(len(line) for line in f)
        print(max(nums))                #对于生成器表达式来说你造出来那生成器开始没有执行任何代码 直到next才刚刚执行一行代码
    print(max(nums))
    print(max(nums))
    
    
    
    l=['egg%s' %i for i in range(100)]
    print(l)
    
    g=('egg%s' %i for i in range(1000000000000))
    # print(g)
    print(next(g))
    print(next(g))

    列表生成式相当于直接给了一筐鸡蛋,而生成器表达式,直接给了一只鸡,
    只鸡可以无限的下蛋,同一时间只有一个鸡蛋,先拉先吃,而列表要来一个真正的空间存进去

      

    今日作业

    今日作业:
    	1、求文件a.txt中总共包含的字符个数?思考为何在第一次之后的n次sum求和得到的结果为0?
    	2、思考题
    		with open('a.txt',encoding='utf-8') as f:
    			g=(len(line) for line in f)
    		print(sum(g))
    
    	3、文件shopping.txt内容如下
    		mac,2000,3
    		lenovo,3000,10
    		tesla,1000000,10
    		chicken,200,1
    
    		求总共花了多少钱?
    		打印出所有的商品信息,格式为
    		[{'name':'xxx','price':'3333','count':3},....]
    		求单价大于10000的商品信息,格式同上
    
    	4、文件内容如下,标题为:姓名,性别,年纪,薪资
    		egon male 18 3000
    		alex male 38 30000
    		wupeiqi female 28 20000
    		yuanhao female 28 10000
    
    		要求:
    		从文件中取出每一条记录放入列表中,
    		列表的每个元素都是{'name':'egon','sex':'male','age':18,'salary':3000}的形式
    
    	5 根据1得到的列表,取出薪资最高的人的信息
    	6 根据1得到的列表,取出最年轻的人的信息
    	7 根据1得到的列表,将每个人的信息中的名字映射成首字母大写的形式
    	8 根据1得到的列表,过滤掉名字以a开头的人的信息
    

      

  • 相关阅读:
    Class.forName()用法详解 【转】
    Java ——代理模式[转发]
    Java堆和栈的区别
    CSS中文字体的英文名称(simsun)宋体,(Microsoft YaHei)微软雅黑
    学了一个封装的jquery插件,感觉还成
    视差滚动(Parallax Scrolling)效果的原理和实现
    解决jQuery中dbclick事件触发两次click事件
    jquery之stop()的用法
    创意 idea
    软件开发方法的综述
  • 原文地址:https://www.cnblogs.com/wangmiaolu/p/9157708.html
Copyright © 2020-2023  润新知