Python中调用函数链的更好方法是什么?

6

我有一系列操作需要依次执行,每个操作都依赖于前一个操作的输出结果。

就像这样:

out1 = function1(initial_input)
out2 = function2(out1)
out3 = function3(out2)
out4 = function4(out3)

这个函数链重复了大约十次,代码看起来有点丑陋。

有没有更好的写法呢?能否使用一些函数式编程技巧来处理它?在调用和执行这个函数链时,有没有更好的方法?


1
我认为你可以使用“reduce”:在这里看看。 - smeso
@Faust 看起来非常有趣。谢谢你分享那个链接! - ComputerFellow
4个回答

7
您可以使用 functools.reduce:
out = functools.reduce(lambda x, y : y(x), [f1, f2, f3, f4], initial_value)
引用 functools.reduce 文档:
应用一个接收两个参数的函数到一个序列的元素上,从左到右逐步减少序列为一个值。例如,reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) 计算 ((((1+2)+3)+4)+5)。如果有 initial,则它将被放置在计算中序列的元素之前,并在序列为空时作为默认值。
在这里,我们利用 Python 中函数可以被视为任何变量的事实,并使用一个匿名函数来简单地执行“将 x 应用于函数 y”。
这个“reduce”操作是一个非常普遍的模式的一部分,已经成功地应用于并行化任务(参见 http://en.wikipedia.org/wiki/MapReduce)。

哈哈,这看起来很神奇!谢谢! :) 你能简单解释一下这个吗? - ComputerFellow
@phg 和 Nicolas - 只是想知道这个解决方案与 falsetru 给出的迭代(for 循环)答案相比性能如何。 - ComputerFellow
我在一个玩具示例上使用for循环计时为4微秒对比3微秒。但我不知道这是否非常相关。 - Nicolas Barbey

5

使用循环:

out = initial_input
for func in [function1, function2, function3, function4]:
    out = func(out)

哇,我为什么没想到这个?这太聪明了! - ComputerFellow
1
你也不需要使用 [],这个也可以:for fn in f1, f2, f3: - thebjorn
@thebjorn,谢谢您的评论。我不知道那个。 - falsetru
@thebjorn,我正在阅读for语句 :) - falsetru
@falsetru :-) 点击 expression_list 链接查看:http://docs.python.org/2/reference/expressions.html#expression-lists - thebjorn

2

为了推广函数式编程:
In [1]: compose = lambda f, g: lambda arg: f(g(arg))

In [2]: from functools import reduce

In [3]: funcs = [lambda x:x+1, lambda x:x*2]

In [4]: f = reduce(compose, funcs)

In [5]: f(1)
Out[5]: 3

In [6]: f(3)
Out[6]: 7

1
你可以直接将返回值传递给下一个函数:
out4 = function4(function3(function2(function1(initial_input))))

但这并不一定更好,也许更难阅读。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接