from collections import namedtuple import random Result = namedtuple('Result', 'count average') # Result格式定义 # 子生成器 def averager(): total = 0.0 count = 0 average = None while True: term = yield # 接收调用方.send传入的值并赋值给term, 返回为None if term is None: break # 调用方传入None结束 total += term count += 1 average = total/count return Result(count, average) # 返回值给委派生成器的results[key](报StopIteration异常,并把值赋值给异常的value,yield from会自动处理该异常并取值) # 委派生成器 def grouper(results, key): while True: results[key] = yield from averager() # 每次传入None后,获取子生成器return的值 # yield from: 子生成器会接管委派生成器的控制权,直到子生成器结束后委派生成器恢复执行 # 调用方 def main(data): results = {} for key, values in data.items(): group = grouper(results, key) next(group) # 激活子生成器 for value in values: group.send(value) # 传入数据,term=yield接收 group.send(None) # 子生成器结束信号 print(results) # {'girls;kg': Result(count=10, average=42.040000000000006), # 'girls;m': Result(count=10, average=1.4279999999999997), # 'boys;kg': Result(count=9, average=40.422222222222224), # 'boys;m': Result(count=9, average=1.3888888888888888)} report(results) # 输出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)) # 最终输出结果 # 9 boys averaging 40.42kg # 9 boys averaging 1.39m # 10 girls averaging 42.04kg # 10 girls averaging 1.43m 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)
python-委派生成器
于 2023-03-26 15:33:47 首次发布