在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/Python/ 協(xié)程中的委派生成器如何停止循環(huán)?

協(xié)程中的委派生成器如何停止循環(huán)?

本人最近在學(xué)習(xí)Python中的協(xié)程知識。在感嘆yield from構(gòu)造的委派生成器能夠連通子生成器和待處理數(shù)據(jù)的同時,遇到一處細(xì)節(jié)苦思不解,下面詳述我的問題。

問題描述:
在下面的實例中,我們需要利用委派生成器的知識將某班級的男女生身高和體重分別計算平均值并輸出。下面的代碼是可以算出正確結(jié)果的。

但是我不理解,委派生成器(就是averager())在每次傳輸給子生成器數(shù)據(jù)的并接受子生成器反饋的過程中,對應(yīng)的while True循環(huán)是如何停止并進(jìn)入新一輪平均值的計算的呢?是因為子生成器break的影響嗎?

希望明白的前輩幫忙指點(diǎn),感激不盡?。?!

from collections import namedtuple

Result=namedtuple('Result','average number')

def subaverager():
    total = 0.0
    number = 0
    average = None
    while True:
        term = yield
        if term is None:
            break
        total += term
        number += 1
        average=total/number
    return Result(average,number)

def averager(results,key):
    while True:
        results[key]=yield from subaverager()

def main(grouper):
    results={}
    for key,group in grouper.items():
        term = averager(results,key)
        next(term)
        for value in group:
            term.send(value)
        term.send(None)
    result(results)
    
def result(results):
    for key,value in results.items():
        gender,unit=key.split(';')
        print('{} {} averaging {:.2f} {}.'.format(
            value.number,gender,value.average,unit))

data = {
'girls;kg':
[40.9, 38.5, 44.3, 42.2, 45.2, 41.7, 44.5, 38.0, 40.6, 44.5],
'girls;m':
[1.6, 1.51, 1.4, 1.3, 1.41, 1.39, 1.33, 1.46, 1.45, 1.43],
'boys;kg':
[39.0, 40.8, 43.2, 40.8, 43.1, 38.6, 41.4, 40.6, 36.3],
'boys;m':
[1.38, 1.5, 1.32, 1.25, 1.37, 1.48, 1.25, 1.49, 1.46],
}

if __name__=='__main__':
    main(data)

輸出如下:

10 girls averaging 42.04 kg.
10 girls averaging 1.43 m.
9 boys averaging 40.42 kg.
9 boys averaging 1.39 m.
回答
編輯回答
涼薄

averager的while True并沒有停止,而是main的for循環(huán)停止了,所以沒有在next(term)。averager因為while true生成器不會停止,你可以一直next(term)。新的一輪計算是因為term = averager(results,key)又構(gòu)造了一個新的生成器。

去掉while true版本,有值啊,你怎么寫的?

from collections import namedtuple

Result=namedtuple('Result','average number')

def subaverager():
    total = 0.0
    number = 0
    average = None
    while True:
        term = yield
        if term is None:
            break
        total += term
        number += 1
        average=total/number
    return Result(average,number)

def averager(results,key):
    results[key]=yield from subaverager()

def main(grouper):
    results={}
    for key,group in grouper.items():
        term = averager(results,key)
        next(term)
        for value in group:
            term.send(value)
        try:
            term.send(None)
        except StopIteration:
            pass
    result(results)
    
def result(results):
    for key,value in results.items():
        gender,unit=key.split(';')
        print('{} {} averaging {:.2f} {}.'.format(
            value.number,gender,value.average,unit))

data = {
'girls;kg':
[40.9, 38.5, 44.3, 42.2, 45.2, 41.7, 44.5, 38.0, 40.6, 44.5],
'girls;m':
[1.6, 1.51, 1.4, 1.3, 1.41, 1.39, 1.33, 1.46, 1.45, 1.43],
'boys;kg':
[39.0, 40.8, 43.2, 40.8, 43.1, 38.6, 41.4, 40.6, 36.3],
'boys;m':
[1.38, 1.5, 1.32, 1.25, 1.37, 1.48, 1.25, 1.49, 1.46],
}

if __name__=='__main__':
    main(data)
2017年11月26日 07:30