python生成器

优点:不会一下子在内存中生成太多数据

'''
生成器案例
需要一个生产一个
可以使用g.__next__()
或for 循环来逐步获取
'''
def produce():
    """生产衣服"""
    for i in range(2000000):
        yield "生产了第%s件衣服"%i

product_g = produce()
print(product_g.__next__()) #要一件衣服
print(product_g.__next__()) #再要一件衣服
print(product_g.__next__()) #再要一件衣服

num = 0
for i in product_g:         #要一批衣服,比如5件
    print(i)
    num +=1
    if num == 15:
        break

#到这里我们找工厂拿了8件衣服,我一共让我的生产函数(也就是produce生成器函数)生产2000000件衣服。
#剩下的还有很多衣服,我们可以一直拿,也可以放着等想拿的时候再拿
def generator():
    print(123)
    content = yield 1
    print('=======',content)
    print(456)
    yield 2

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

#send 获取下一个值的效果和next基本一致
#只是在获取下一个值的时候,给上一yield的位置传递一个数据
#使用send的注意事项
    # 第一次使用生成器的时候 是用next获取下一个值
    # 最后一个yield不能接受外部的值
'''
通过生成器实现平均数
循环输入新的数字,同时生成新的平均数
'''
def averager():
    total = 0.0
    count = 0
    l=[]
    average = None
    while True:
        term = yield average,l#返回平均值,列表
        l.append(term)
        total += term
        count += 1
        average = total/count


g_avg = averager()
next(g_avg)
print(g_avg.send(10))
print(g_avg.send(10))
print(g_avg.send(10))
#循环调用生成器
while True:
    num=input("新数字:")
    print(g_avg.send(int(num)))
'''
通过装饰器,执行next方法
使用语法糖调用
'''
def init(func):  #在调用被装饰生成器函数的时候首先用next激活生成器
    def inner(*args,**kwargs):
        g = func(*args,**kwargs)
        next(g)
        return g
    return inner

@init
def averager():
    total = 0.0
    count = 0
    average = None
    while True:
        term = yield average
        total += term
        count += 1
        average = total/count


g_avg = averager()
# next(g_avg)   在装饰器中执行了next方法
print(g_avg.send(10))
print(g_avg.send(30))
print(g_avg.send(5))
'''
两种生成器的下发实现相同的效果

'''

def gen1():
    for c in 'AB':
        yield c
    for i in range(3):
        yield i

print(list(gen1()))

def gen2():
    yield from 'AB'
    yield from range(3)

print(list(gen2()))
'''
next()和__next__本质是一样的
'''

egg_list=['鸡蛋%s' %i for i in range(10)] #列表解析
laomuji=('鸡蛋%s' %i for i in range(10))#生成器表达式
print(laomuji)
print(next(laomuji)) #next本质就是调用__next__
print(laomuji.__next__())
print(next(laomuji))
原文地址:https://www.cnblogs.com/huay/p/10837705.html