[英]How to compose a list of functions in steps in Python using map and reduce
给定一个函数(函数)列表和一个 integer n,我试图找出一种逐步组合它们的方法,并返回每个逐步结果的列表,如下所示:
compose_step([lambda x: x+3, lambda x: x+5, lambda x: x+1], 8) --> [8, 11, 16, 17]
所以,到目前为止,我已经想出了如何组成一个函数列表并返回结果如下:
def compose(functions, n):
def compose2(f,g):
return lambda x: f(g(x))
composedFunction = functools.reduce(compose2, functions, lambda x: x)
return composedFunction(n)
但是,我非常困惑如何跟踪每个步骤并将其作为列表返回。 我假设我需要以某种方式使用 map 以便 map 每个逐步进入列表。 我还提出了一种将列表中的所有函数应用于 n 的方法:
def apply_all_functions(functions, n):
answerList = list(map(methodcaller('__call__', n), functions)))
return answerList
我正在考虑以某种方式使用 composeFunction function 来组成一个新的逐步函数列表,一直到完全组成 function,然后将其用作 apply_all_functions 的新列表以实现所需的结果。 但目前,我很困惑。
您可以将itertools.accumulate
与组合函数一起使用
from itertools import accumulate
def compose(f, g):
return lambda x: f(g(x))
funcs = [lambda x: x, lambda x: x+3, lambda x: x+5, lambda x: x+1]
print([f(8) for f in accumulate(funcs, compose)])
# [8, 11, 16, 17]
itertools.accumulate
是要走的路,但如果你想知道如何自己做,这是一种方法
def apply_all (x, f = None, *fs):
if f is None:
return []
else:
next = f (x)
return [ next ] + apply_all(next, *fs)
funcs = \
[ lambda x: x
, lambda x: x+3
, lambda x: x+5
, lambda x: x+1
]
print(apply_all(8, *funcs))
# [ 8, 11, 16, 17 ]
如果您需要原始问题中的表格
def apply_all (fs, x):
if not fs:
return []
else:
next = fs[0](x)
return [ next ] + apply_all(fs[1:], next)
funcs = \
[ lambda x: x
, lambda x: x+3
, lambda x: x+5
, lambda x: x+1
]
print(apply_all(funcs, 8))
# [ 8, 11, 16, 17 ]
上述形式在fs[0]
和fs[1:]
,表明这可以表示为香草reduce
from functools import reduce
def apply_all (fs, x):
def reducer (acc, f):
(seq, x) = acc
next = f (x)
return (seq + [next], next)
return reduce(reducer, fs, ([], x)) [0]
funcs = \
[ lambda x: x
, lambda x: x+3
, lambda x: x+5
, lambda x: x+1
]
print(apply_all(funcs, 8))
# [ 8, 11, 16, 17 ]
您还可以使用带有初始值的itertools.accumulate
:
from itertools import accumulate
def compose(data, funcs):
yield from accumulate(funcs, lambda data, f: f(data), initial=data)
funcs = [lambda x: x+3, lambda x: x+5, lambda x: x+1]
init = 8
print(list(compose(init, funcs)))
# [8, 11, 16, 17]
如果您不想要中间结果,可以使用functools.reduce
做类似的事情。
这类似于@Patrick 的回答,但这里accumulate
应用每个 function 并逐个产生逐步结果,而不是生成组合函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.