我无法理解grouper
中的while True:
行,删除该行将引发StopIteration
错误
但是我发现一个新版本的grouper
没有while True:
可以工作。为什么group.send(None)
需要while True:
(或另一个results[key] = yield from averager()
)中的另一个循环
我的理解是group.send(None)
将停止yield from averager()
并为results[key]
分配一个值(Result(count, average)
)。就这些
from collections import namedtuple
Result = namedtuple('Result', 'count average')
# the subgenerator
def averager(): # <1>
total = 0.0
count = 0
average = None
while True:
term = yield # <2>
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>
while True: # <6>
results[key] = yield from averager() # <7>
# Another version works
#def grouper(results, key):
# results[key] = yield from averager()
# results[key] = yield from averager()
# 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)
这让我想起了ascynio有多好,以及为什么每个人都应该使用它
通过遍历迭代器的操作可以最好地解释正在发生的事情。这是内部生成器,简化为:
这有两件事。首先,它通过
yield
获取一些数据(呃,解释单词的选择很混乱),只要这些数据不是None
。然后,当它是None
时,它会引发一个值为local_var
的StopIterationException
。(这就是从发电机返回的功能)这是外部发电机:
这个所做的是将内部生成器的产量公开给调用代码,直到内部生成器引发
StopIterationException
,它被静默地捕获(由yield from
语句)并分配。然后它准备再次做同样的事情然后我们有了调用代码:
这个的作用是:
.send
)与内部生成器通信李>None
(第一个yield from
语句在该点结束)来“结束”内部生成器,并分配向上传递的值李>考虑此代码,它也适用于外部生成器:
唯一重要的是,生成器不应该耗尽,因此它不会向链上传递一个异常,说“我没有什么可迭代的了”
p.S.困惑吗?我是。我必须检查一下,我已经有一段时间没有尝试使用基于发电机的coros了。他们被安排删除-使用asyncio,这比使用asyncio好得多
相关问题 更多 >
编程相关推荐