Python 共享迭代器的单个迭代
我有很多数据,通常在一个文件中。我想计算一些量,所以我有这样的函数:Python 共享迭代器的单个迭代,python,iterator,Python,Iterator,我有很多数据,通常在一个文件中。我想计算一些量,所以我有这样的函数: def mean(iterator): n = 0 sum = 0. for i in iterator: sum += i n += 1 return sum / float(n) 我还有许多其他类似的函数(var,size,…) 现在我有一个迭代器在数据中迭代:iter\u data。我可以计算所有我想要的量:m=mean(iter\u数据);v=var(iter_
def mean(iterator):
n = 0
sum = 0.
for i in iterator:
sum += i
n += 1
return sum / float(n)
我还有许多其他类似的函数(var
,size
,…)
现在我有一个迭代器在数据中迭代:iter\u data
。我可以计算所有我想要的量:m=mean(iter\u数据);v=var(iter_data)
等等,但问题是我迭代了很多次,在我的例子中这是非常昂贵的。实际上,I/O是最昂贵的部分
所以问题是:我能不能计算我的量m,v,…
在iter\u数据上只迭代一次
保持函数mean
,var
。。。这样就很容易添加新的
我需要的是类似的东西,您可以使用和生成器magic(我说magic是因为它不太好读):
顺便说一下,您可以用一种更简单的方式编写mean
:
def mean(iterator):
total = 0.
for n, item in enumerate(iterator, 1):
total += i
yield
yield total / n
您不应该为变量命名
sum
,因为这会隐藏具有相同名称的内置函数。您想要的是有一个主Calc
类,该类对数据进行迭代,对mean
、var
等应用不同的计算,然后可以通过接口返回这些值。您可以让计算在主计算之前向此类注册,然后通过接口中的新访问器获得结果,从而使其更通用。例如,使用对象和回调,如:
class Counter():
def __init__(self):
self.n = 0
def __call__(self, i):
self.n += 1
class Summer():
def __init__(self):
self.sum = 0
def __call__(self, i):
self.sum += i
def process(iterator, callbacks):
for i in iterator:
for f in callbacks: f(i)
counter = Counter()
summer = Summer()
callbacks = [counter, summer]
iterator = xrange(10) # testdata
process(iterator, callbacks)
# process results from callbacks
n = counter.n
sum = summer.sum
这很容易扩展,并且只对数据进行一次迭代。如果没有类,您可以调整以下内容:
def my_mean():
total = 0.
length = 0
while True:
val = (yield)
if val is not None:
total += val
length += 1
else:
yield total / length
def my_len():
length = 0
while True:
val = (yield)
if val is not None:
length += 1
else:
yield length
def my_sum():
total = 0.
while True:
val = (yield)
if val is not None:
total += val
else:
yield total
def process(iterable, **funcs):
fns = {name:func() for name, func in funcs.iteritems()}
for fn in fns.itervalues():
fn.send(None)
for item in iterable:
for fn in fns.itervalues():
fn.send(item)
return {name:next(func) for name, func in fns.iteritems()}
data = [1, 2, 3]
print process(data, items=my_len, some_other_value=my_mean, Total=my_sum)
# {'items': 3, 'some_other_value': 2.0, 'Total': 6.0}
您可以使用一个循环将所有函数绑定到一个函数中,并返回一个包含所有计算值的字典,如
{'mean':2.7,'var':0.2,'size':27}
,等等@MrE:no,在您的解决方案中,您并没有将函数分开,而是以相同的方式计算均值和方差function@Brionius,同样的问题。正如我在问题中所说:将函数分开是不是数据太大,无法放入内存?否则迭代可能会很快,您可以使用例如numpy。
def my_mean():
total = 0.
length = 0
while True:
val = (yield)
if val is not None:
total += val
length += 1
else:
yield total / length
def my_len():
length = 0
while True:
val = (yield)
if val is not None:
length += 1
else:
yield length
def my_sum():
total = 0.
while True:
val = (yield)
if val is not None:
total += val
else:
yield total
def process(iterable, **funcs):
fns = {name:func() for name, func in funcs.iteritems()}
for fn in fns.itervalues():
fn.send(None)
for item in iterable:
for fn in fns.itervalues():
fn.send(item)
return {name:next(func) for name, func in fns.iteritems()}
data = [1, 2, 3]
print process(data, items=my_len, some_other_value=my_mean, Total=my_sum)
# {'items': 3, 'some_other_value': 2.0, 'Total': 6.0}