我在这里为您提供了两种可能的解决方案。两者都是适用于任何数字列表的通用运行平均函数。(可以使用任何可迭代的)
基于生成器:
nums = [cauchy(3,1) for x in xrange(10)]
def running_avg(numbers):
for count in xrange(1, len(nums)+1):
yield sum(numbers[:count])/count
print list(running_avg(nums))
基于列表理解(实际上与前面的代码相同):
nums = [cauchy(3,1) for x in xrange(10)]
print [sum(nums[:count])/count for count in xrange(1, len(nums)+1)]
基于发电机兼容的发电机:
编辑:我刚刚测试了这个,看看我是否可以轻松地使我的解决方案与生成器兼容,以及它的性能是什么。这就是我想出的。
def running_avg(numbers):
sum = 0
for count, number in enumerate(numbers):
sum += number
yield sum/(count+1)
请参阅下面的性能统计数据,非常值得。
性能特点:
编辑:我还决定测试 Orip 对多个生成器的有趣使用,以查看对性能的影响。
使用 timeit 和以下(1,000,000 次迭代 3 次):
print "Generator based:", ', '.join(str(x) for x in Timer('list(running_avg(nums))', 'from __main__ import nums, running_avg').repeat())
print "LC based:", ', '.join(str(x) for x in Timer('[sum(nums[:count])/count for count in xrange(1, len(nums)+1)]', 'from __main__ import nums').repeat())
print "Orip's:", ', '.join(str(x) for x in Timer('list(itertools.islice(running_avgs, 10))', 'from __main__ import itertools, running_avgs').repeat())
print "Generator-compatabile Generator based:", ', '.join(str(x) for x in Timer('list(running_avg(nums))', 'from __main__ import nums, running_avg').repeat())
我得到以下结果:
Generator based: 17.653908968, 17.8027219772, 18.0342400074
LC based: 14.3925321102, 14.4613749981, 14.4277560711
Orip's: 30.8035550117, 30.3142540455, 30.5146529675
Generator-compatabile Generator based: 3.55352187157, 3.54164409637, 3.59098005295
代码见注释:
Orip's genEx based: 4.31488609314, 4.29926609993, 4.30518198013
结果以秒为单位,并显示LC新的发生器兼容发生器方法始终更快,但您的结果可能会有所不同。我预计我的原始生成器和新生成器之间的巨大差异在于总和不是即时计算的。