• day14 生成器函数进阶和生成器表达式


    1复习

    # 迭代器和生成器
    # 迭代器:
    # 双下方法 : 很少直接调用的方法。一般情况下,是通过其他语法触发的
    # 可迭代的 —— 可迭代协议 含有__iter__的方法('__iter__' in dir(数据))
    # 可迭代的一定可以被for循环
    # 迭代器协议: 含有__iter__和__next__方法
    # 迭代器一定可迭代,可迭代的通过调用iter()方法就能得到一个迭代器
    # 迭代器的特点:
        # 很方便使用,且只能取所有的数据取一次
        # 节省内存空间
    
    # 生成器
    # 生成器的本质就是迭代器
    # 生成器的表现形式
        # 生成器函数
        # 生成器表达式
    # 生成器函数:
        #含有yield关键字的函数就是生成器函数
        #特点:
            #调用函数的之后函数不执行,返回一个生成器
            #每次调用next方法的时候会取到一个值
            #直到取完最后一个,在执行next会报错
    def generator():
        for i in range(6):
            yield '哇哈哈%s'%i
    
    g = generator()  #调用生成器函数得到一个生成器
    print(list(g)) #再取值会报错
    
    <<<
    ['哇哈哈0', '哇哈哈1', '哇哈哈2', '哇哈哈3', '哇哈哈4', '哇哈哈5']
    
    
    def generator():
    for i in range(6):
    yield '哇哈哈%s'%i
    g = generator()
    ret = g.__next__() #每一次执行g.__next__就是从生成器中取值,预示着生成器函数中的代码继续执行
    print(ret)
    num = 0
    for i in g:
    num += 1
    if num > 3:
    break
    print(i)
    <<<

    哇哈哈0
    哇哈哈1
    哇哈哈2
    哇哈哈3

     
    # 从生成器中取值的几个方法
        # next
        # for
        # 数据类型的强制转换 : 占用内存

    2生成器函数进阶

    1send

    
    
    def generator():
    print(123)
    content = yield 1
    print('=======',content)
    print(456)
    arg = yield 2
    ''''''
    yield
    g1 = generator()
    g2 = generator()
    g1.__next__()
    g2.__next__()
    print('***',generator().__next__())
    print('***',generator().__next__())

    g = generator()
    ret = g.__next__()
    print('***',ret)
    ret = g.send('hello') #send的效果和next一样
    print('***',ret)

    #send 获取下一个值的效果和next基本一致
    #只是在获取下一个值的时候,给上一yield的位置传递一个数据
    #使用send的注意事项
    # 第一次使用生成器的时候 是用next获取下一个值
    # 最后一个yield不能接受外部的值
    <<<

    123
    123
    123
    *** 1
    123
    *** 1
    123
    *** 1
    ======= hello
    456
    *** 2

     

    2计算移动平均值

    def average():
        sum = 0
        count = 0
        avg = 0
        while True:
            num = yield avg
            sum += num    # 10
            count += 1    # 1
            avg = sum/count
    
    avg_g = average()
    avg_g.__next__()
    avg1 = avg_g.send(10)
    avg1 = avg_g.send(20)
    print(avg1)
    <<<
    15.0

    3预激生成器的装饰器

    def average():
        sum = 0
        count = 0
        avg = 0
        while True:
            num = yield avg
            sum += num    # 10
            count += 1    # 1
            avg = sum/count
    
    avg_g = average()
    avg_g.__next__()
    avg1 = avg_g.send(10)
    avg1 = avg_g.send(20)
    print(avg1)
    <<<
    10.0
    15.0

    4yield from

    def generator():
        a = 'abcde'
        b = '12345'
        for i in a:
            yield i
        for i in b:
            yield i
    def generator():
        a = 'abcde'
        b = '12345'
        yield from a
        yield from b
    g = generator()
    for i in g:
        print(i)
    <<<
    a
    b
    c
    d
    e
    1
    2
    3
    4
    5
    # send
        # send的作用范围和next一模一样
        # 第一次不能用send
        # 函数中的最后一个yield不能接受新的值
    
    # 计算移动平均值的例子
    # 预激生成器的装饰器的例子
    # yield from
  • 相关阅读:
    BZOJ3514:GERALD07加强版(LCT,主席树)
    BZOJ2729:[HNOI2012]排队(组合数学)
    BZOJ4517:[SDOI2016]排列计数(组合数学,错排公式)
    BZOJ3123:[SDOI2013]森林(主席树,启发式合并)
    BZOJ3786:星系探索(Splay,括号序)
    BZOJ2212:[POI2011]Tree Rotations(线段树合并)
    BZOJ5329:[SDOI2018]战略游戏(圆方树,虚树)
    CF613D:Kingdom and its Cities(树形DP,虚树)
    BZOJ3611:[HEOI2014]大工程(树形DP,虚树)
    BZOJ2286:[SDOI2011]消耗战(树形DP,虚树)
  • 原文地址:https://www.cnblogs.com/hi-python/p/10143627.html
Copyright © 2020-2023  润新知