Python:功能合并两个迭代器,其中一个是递归的

时间:2015-11-08 23:33:35

标签: python recursion functional-programming iterator generator

相关问题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了解或关心。

1 个答案:

答案 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中。