我有一组功能f(x), g(x), s(x), t(x)
。
它们被设计成这样链接在一起:f(g(s(t(x))))
这些功能经过设计,因此可以按任何顺序链接。我的代码的另一部分在列表中构建序列:[f, g, s, t]
是否有一种优雅方法来获取列表并链接函数调用,以获取最后结果的输出?
现在显然我可以使用类似外部计数器的变量来跟踪输出并使用简单的for
循环增量索引来做到这一点,但是我想知道是否还有其他Python方式可以做到这一点?
答案 0 :(得分:4)
Reduce是一个完美的答案(尽管我们需要从最里面的功能开始,因此reversed
):
import functools
functions = [f, g, s, t]
y = functools.reduce(lambda a, f: f(a), reversed(functions), x)
编辑:使用常量参数,就像这样简单:
p1, p2 = 5, 42
y = functools.reduce(lambda a, f: f(a, p1, p2), reversed(functions), x)
答案 1 :(得分:3)
Martineau和Amadan已经发布了“优雅”的解决方案。现在真正的pythonic解决方案是愚蠢的,尽可能简单地变得无聊:
def chain(arg, *funcs):
# chain(42, f, g, s) => f(g(s(42)))
result = arg
for func in reversed(funcs):
result = func(result)
return result
显然不是大多数人认为的“优雅”,但是它非常明显,易读并且非常易于跟踪和调试-这就是大多数wrt / python的哲学所在。
答案 2 :(得分:1)
在函数式编程中,此操作称为函数组合。 Python在标准库中没有compose函数,但是编写自己很容易:
from functools import partial
# additional import for python 3: from itertools import reduce
def compose(*args):
return partial(reduce, lambda x, y: y(x), reversed(args))
然后您可以编写类似的功能
fgst_x = compose(f, g, s, t)(x)
或
funcs = [f, g, s, t]
fgst = compose(*funcs)
fgst_x = fgst(x)