Vie*_*iet 12 python functional-programming
我有一个输入值val和一个要在顺序中应用的函数列表:
funcs = [f1, f2, f3, ..., fn]
Run Code Online (Sandbox Code Playgroud)
如何优雅地应用而不是写作
fn( ... (f3(f2(f1(val))) ... )
Run Code Online (Sandbox Code Playgroud)
并且也没有使用for循环:
tmp = val
for f in funcs:
tmp = f(tmp)
Run Code Online (Sandbox Code Playgroud)
感谢Martijn的精彩回答.我找到了一些阅读:https://mathieularose.com/function-composition-in-python/.
Mar*_*ers 22
使用reduce()功能:
# forward-compatible import
from functools import reduce
result = reduce(lambda res, f: f(res), funcs, val)
Run Code Online (Sandbox Code Playgroud)
reduce()将第一个参数(一个可调用的)应用于从第二个参数中取出的每个元素,加上到目前为止的累积结果(as (result, element)).第三个参数是一个起始值(funcs否则将使用第一个元素).
在Python 3中,内置函数被移动到该functools.reduce()位置 ; 为了向前兼容,Python 2.6及更高版本中提供了相同的参考.
其他语言可称为折叠.
如果您还需要每个函数的中间结果,请使用itertools.accumulate()(仅从Python 3.3开始,以获取带有函数参数的版本):
from itertools import accumulate, chain
running_results = accumulate(chain(val, funcs), lambda res, f: f(res))
Run Code Online (Sandbox Code Playgroud)
MartijnPieters 的回答非常好。我唯一要补充的是,这称为函数组合
为这些泛型命名意味着您可以在需要时使用它们
from functools import reduce
def id(x):
return x
def comp(f,g):
return lambda x: f(g(x))
def compose(*fs):
return reduce(comp, fs, id)
# usage
# compose(f1, f2, f3, ..., fn) (val)
print(compose (lambda x: x + 1, lambda x: x * 3, lambda x: x - 1) (10))
# = ((10 - 1) * 3) + 1
# = 28
Run Code Online (Sandbox Code Playgroud)
有时你希望它看起来更好 -
def seq (x): return lambda k: seq (k (x))
def fn1 (x): return x - 1
def fn2 (x): return x * 3
def fn3 (x): return x + 1
seq (10) (fn1) (fn2) (fn3) (print) # 28
# 10 9 27 28
Run Code Online (Sandbox Code Playgroud)
有时你想要更多的灵活性——
from operator import add, mul, sub
def seq (x):
return lambda k, *v: seq (k (x, *v))
seq (10) (sub, 1) (mul, 3) (add, 1) (print) # 28
# 10 9 27 28
seq (1) (add, 2) (add, 3) (add, 4) (add, 5) (print) # 15
# 1 3 6 10 15
Run Code Online (Sandbox Code Playgroud)