问题描述
我有一个输入值 val
和一个按顺序应用的函数列表:
I have an input value val
and a list of functions to be applied in the order:
funcs = [f1, f2, f3, ..., fn]
如何优雅地应用而不是写作
How to apply elegantly and not writing
fn( ... (f3(f2(f1(val))) ... )
并且也不使用 for 循环:
and also not using for loop:
tmp = val
for f in funcs:
tmp = f(tmp)
感谢 Martijn 的精彩回答.我发现了一些阅读:https://mathieularose.com/function-composition-in-python/ .
Thanks Martijn for the awesome answer. There's some reading I found: https://mathieularose.com/function-composition-in-python/ .
推荐答案
使用 reduce()
函数:
Use the reduce()
function:
# forward-compatible import
from functools import reduce
result = reduce(lambda res, f: f(res), funcs, val)
reduce()
将第一个参数,一个可调用的,应用于从第二个参数中取出的每个元素,加上到目前为止的累积结果(如 (result, element)
).第三个参数是一个起始值(否则将使用 funcs
中的第一个元素).
reduce()
applies the first argument, a callable, to each element taken from the second argument, plus the accumulated result so far (as (result, element)
). The third argument is a starting value (the first element from funcs
would be used otherwise).
在 Python 3 中,内置函数被移至 functools.reduce() 位置;为了向前兼容,Python 2.6 及更高版本中提供了相同的参考.
In Python 3, the built-in function was moved to the functools.reduce()
location; for forward compatibility that same reference is available in Python 2.6 and up.
其他语言可能将此称为折叠.
Other languages may call this folding.
如果您还需要每个函数的中间结果,请使用 itertools.accumulate()
(仅从 Python 3.3 开始,对于采用函数参数的版本):
If you need intermediate results for each function too, use itertools.accumulate()
(only from Python 3.3 onwards for a version that takes a function argument):
from itertools import accumulate, chain
running_results = accumulate(chain(val, funcs), lambda res, f: f(res))
这篇关于优雅地按顺序应用 Python 函数列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!