相关问题How do I merge two python iterators?适用于两个独立的迭代器。但是,我还没有找到或想到合并两个迭代器所需的工具,其中一个是递归的,另一个是输入。我有迭代器stuff
这是一个简单的列表。然后我有一个迭代器theta
,它接受一个函数func
并产生x,func(x),func(func(x)),其中func
的一个输入是一个元素stuff
。我已经用可变状态解决了这个问题,如下所示:
theta = some_initial_theta
for thing in stuff:
theta = update_theta(theta, thing)
return theta
此格式的具体示例:
def update_theta(theta, thing):
return thing * 2 + theta
stuff = [100, 200, 300, 400]
def my_iteration():
theta = 0
for thing in stuff:
theta = update_theta(theta, thing)
print(theta)
# This prints 2000
我确信没有可变状态和for循环,这是一种优雅的方式。一个简单的zip对我来说没有,因为theta
迭代器使用它的前一个元素作为下一个元素的输入。
表达theta的一种优雅方式是使用more_itertools package中提供的iterate
方法:
iterate(lambda theta: update_theta(theta, thing), some_initial_theta)
然而,问题是thing
将在整个迭代过程中得到修复。可以通过传入整个列表stuff
来处理这个问题,然后从update_theta方法返回其余部分:
iterate(lambda theta: update_theta(theta[0], theta[1]), (some_initial_theta, stuff))
但是,我真的不想修改update_theta
方法来获取它不感兴趣的整个列表并处理返回该列表尾部的机制。虽然它在编程上并不困难,但它的关注点很差。 update_theta
不应该对整个列表stuff
了解或关心。
答案 0 :(得分:4)
正如Peter Wood在评论中所说,这是完全内置函数reduce
的作用:
result = reduce(update_theta, stuff, some_initial_theta)
在Python 3中,reduce
已移至functools.reduce
,因此您需要导入该内容:
from functools import reduce
如果需要所有中间值的迭代器,Python 3提供itertools.accumulate
。没有参数指定初始值,因此您需要将初始值放在迭代器中:
from itertools import accumulate, chain
result_iterator = accumulate(chain([some_initial_theta], stuff), update_theta)
Python 2没有itertools.accumulate
,但您可以从Python 3文档中复制等效代码。根据Python 2标准工具,没有简单的方法来制定它,这就是为什么人们希望它首先添加到Python 3中。