流利的python:从子生成器委托生成器收益为什么要调用两次?

时间:2019-04-25 03:39:25

标签: python-3.x

我正在读书:流利的python。我对“ yield from”的使用感到困惑。

代码在这里:

from collections import namedtuple

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


# the subgenerator
def averager():  # <1>
    total = 0.0
    count = 0
    average = None
    print("\t\taverger init!")
    while True:
        print("\t\t\taverger run!")
        term = yield  # <2>
        print("\t\t\t\tterm is {}".format(term))
        if term is None:  # <3>
            break
        total += term
        count += 1
        average = total/count
    return Result(count, average)  # <4>


# the delegating generator
def grouper(results, key):  # <5>
    print("grouper init!")
    while True:  # <6>
        print("\tgrouper run!")
        results[key] = yield from averager()  # <7>
        print("\t{}".format(results[key]))

# the client code, a.k.a. the caller
def main(data):  # <8>
    results = {}
    for key, values in data.items():
        group = grouper(results, key)  # <9>
        next(group)  # <10>
        for value in values:
            group.send(value)  # <11>
        group.send(None)  # important! <12>

    # print(results)  # uncomment to debug
    report(results)


# output report
def report(results):
    for key, result in sorted(results.items()):
        group, unit = key.split(';')
        print('{:2} {:5} averaging {:.2f}{}'.format(
              result.count, group, result.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)

,结果显示为:

grouper init!
        grouper run!
                averger init!
                        averger run!
                                term is 40.9
                        averger run!
                                term is 38.5
                        averger run!
                                term is 44.3
                        averger run!
                                term is 42.2
                        averger run!
                                term is 45.2
                        averger run!
                                term is 41.7
                        averger run!
                                term is 44.5
                        averger run!
                                term is 38.0
                        averger run!
                                term is 40.6
                        averger run!
                                term is 44.5
                        averger run!
                                term is None
        Result(count=10, average=42.040000000000006)
        grouper run!
                averger init!
                        averger run!
grouper init!
        grouper run!
                averger init!
                        averger run!
                                term is 1.6
                        averger run!
                                term is 1.51
                        averger run!
                                term is 1.4
                        averger run!
                                term is 1.3
                        averger run!
                                term is 1.41
                        averger run!
                                term is 1.39
                        averger run!
                                term is 1.33
                        averger run!
                                term is 1.46
                        averger run!
                                term is 1.45
                        averger run!
                                term is 1.43
                        averger run!
                                term is None
        Result(count=10, average=1.4279999999999997)
        grouper run!
                averger init!
                        averger run!
grouper init!
        grouper run!
                averger init!
                        averger run!
                                term is 39.0
                        averger run!
                                term is 40.8
                        averger run!
                                term is 43.2
                        averger run!
                                term is 40.8
                        averger run!
                                term is 43.1
                        averger run!
                                term is 38.6
                        averger run!
                                term is 41.4
                        averger run!
                                term is 40.6
                        averger run!
                                term is 36.3
                        averger run!
                                term is None
        Result(count=9, average=40.422222222222224)
        grouper run!
                averger init!
                        averger run!
grouper init!
        grouper run!
                averger init!
                        averger run!
                                term is 1.38
                        averger run!
                                term is 1.5
                        averger run!
                                term is 1.32
                        averger run!
                                term is 1.25
                        averger run!
                                term is 1.37
                        averger run!
                                term is 1.48
                        averger run!
                                term is 1.25
                        averger run!
                                term is 1.49
                        averger run!
                                term is 1.46
                        averger run!
                                term is None
        Result(count=9, average=1.3888888888888888)
        grouper run!
                averger init!
                        averger run!
 9 boys  averaging 40.42kg
 9 boys  averaging 1.39m
10 girls averaging 42.04kg
10 girls averaging 1.43m

我很困惑:

1:为什么在“ grouper”函数中使用“ while”?

2:为什么“石斑鱼跑!”在grouper函数调用中显示两次?

3:为什么最后一次“平均跑”!在“石斑鱼跑!”中不打印“条件”的值?

4:“收益”实际上是做什么的?

0 个答案:

没有答案