zoukankan      html  css  js  c++  java
  • 生成器

    一 生成器与yield

      若函数体包含yield关键字,再调用函数,并不会执行函数体代码,得到的返回值即生成器对象

    def func():
        print('第一次')
        yield 1
        print('第二次')
        yield 2
        print('第三次')
        yield 3
        print('第四次')    
    g=func()
    print(g)
    #生成器就是迭代器
    g.__iter__()
    g.__next__()
    
    # 会触发函数体代码的运行,然后遇到yield停下来,将yield后的值
    # 当做本次调用的结果返回
    res=g.__next__()
    print(res)
    
    # 应用案列
    def my_range(start,stop,step=1):
        # print('start...')
        while start < stop:
            yield start
            start+=step
        # print('end....')
    
    for n in my_range(1,7,2):
        print(n)

      总结yield:有了yield关键字,我们就有了一种自定义迭代器的实现方式。yield可以用于返回值,但不同于return,函数一旦遇到return就结束了,而yield可以保存函数的运行状态挂起函数,用来返回多次值

    二 yield表达式应用

      在函数内可以采用表达式形式的yield

    def dog(name):
        print('%s准备吃东西啦'%name)
        while True:
            # x拿到的是yield接收到的值
            x = yield
            print('%s吃了 %s' %(name,x))

      可以拿到函数的生成器对象持续为函数体send值,如下

    g=dog('alex')
    g.send(None) # 等同于next(g)
    
    g.send('肉包子')
    g.send('一同泔水')
    g.close()
    g.send('1111') # 关闭之后无法传值

      针对表达式形式的yield,生成器对象必须事先被初始化一次,让函数挂起在food=yield的位置,等待调用g.send()方法为函数体传值,g.send(None)等同于next(g)。

      表达式形式的yield也可以用于返回多次值,即变量名=yield 值的形式,如下

    def dog(name):
        food_list=[]
        print('道哥%s准备吃东西啦...' %name)
        while True:
            # x拿到的是yield接收到的值
            x = yield food_list # x = '肉包子'
            print('道哥%s吃了 %s' %(name,x))
            food_list.append(x) # ['一根骨头','肉包子']
    g=dog('alex')
    res=g.send(None)  # next(g)
    print(res)
    
    res=g.send('一根骨头')
    print(res)
    
    res=g.send('肉包子')
    print(res)

    三 三元表达式、列表生成式、生成器表达式

      3.1三元表达式

      三元表达式是python为我们提供的一种简化代码的解决方案,语法如下

    res = 条件成立时返回的值 if 条件 else 条件不成立时返回的值

      针对下述场景

    def func(x,y):
        if x > y:
            return x
        else:
            return y
    res=func(1,2)

      用三元表达式可以一行解决

    x=1
    y=2
    res = x if x > y else y # 三元表达式

      

      3.2列表生成式

        列表生成式是python为我们提供的一种简化代码的解决方案,用来快速生成列表

         针对如下场景:

    l = ['alex_dsb', 'lxx_dsb', 'wxx_dsb', "xxq_dsb", 'egon']
    new_l=[]
    for name in l:
        if name.endswith('dsb'):
            new_l.append(name)

        用列表生成式可以一行解决

    new_l=[name for name in l if name.endswith('dsb')]

      3.3生成器扩展 

        字典生成式

    keys=['name','age','gender']
    dic={key:None for key in keys}
    print(dic)
    
    items=[('name','egon'),('age',18),('gender','male')]
    res={k:v for k,v in items if k != 'gender'}
    print(res)

        集合生成式

    keys=['name','age','gender']
    set1={key for key in keys}
    print(set1,type(set1))

      3.4生成器表达式

      创建一个生成器对象有两种方式,一种是调用带yield关键字的函数,另一种就是生成器表达式,与列表生成式的语法格式相同,只需要将[]换成()

    (expression for item in iterable if condition)

      对比列表生成式返回的是一个列表,生成器表达式返回的是一个生成器对象

    g=(i for i in range(10) if i > 3)
    # !!!!!!!!!!!强调!!!!!!!!!!!!!!!
    # 此刻g内部一个值也没有
    print(g,type(g))
    print(g)
    print(next(g))#调用一次next才会有一个值
    print(next(g))

      如果我们要读取一个大文件的字节数,应该基于生成器表达式的方式完成

    with open('笔记.txt', mode='rt', encoding='utf-8') as f:
        res = sum(len(line) for line in f)
        print(res)
  • 相关阅读:
    前端小tite(随笔)
    算法两数之和 python版
    常用标签
    pip install 遇到的问题
    不常用的模块
    约束和约束关系
    Django初识
    前端—Bootstrap
    前端—jQuery
    前端—BOM和DOM
  • 原文地址:https://www.cnblogs.com/bk134/p/12560422.html
Copyright © 2011-2022 走看看