我试图将我的Javascript撰写函数转换为Python,但我遇到了最后一个问题。如何推广未知数量的函数?
阅读this后,我想避免使用reduce()
方法。
的javascript:
/* compose functions */
const comp1 = (fn2, fn1) => arr => fn2(fn1(arr)) // 2 functions, one array
const comp2 = (fn2, fn1) => (...arrs) => fn2(fn1(...arrs)) // 2 functions, multiple arrays
const comp3 = (...fns) => (...arrs) => fns.reduceRight((v,f) => f(v), arrs) // multiple functions, multiple arrays
蟒:
/* compose functions */
comp1 = lambda fn2,fn1: lambda arr: fn2(fn1(arr)) # 2 functions, 1 array
comp2 = lambda fn2,fn1: lambda *arrs: fn2(fn1(*arrs)) # 2 functions, multiple arrays
comp3 = lambda *fns: lambda *arrs: ????
赞赏所有改进......
答案 0 :(得分:1)
如果你真的不想使用reduce
,我认为这是正确的方法,你可以有一个循环。尽管如此,这会阻止您使用lambda
。
def compose(*fns):
def composed(*args, **kwargs):
output = fns[-1](*args, **kwargs)
for fn in reversed(fns[:-1]):
output = fn(output)
return output
return composed
我想再次声明没有理由不使用reduce
,因为上面只是reduce的具体实现。组成是减少。
from functools import reduce # Only required in Python3 where reduce was moved
def compose(f1, f2):
return lambda *args, **kwargs: f1(f2(*args, **kwargs))
def compose_many(*fns):
return reduce(compose, fns, lambda x: x)
答案 1 :(得分:1)
这是一个很好的可变参数,用于促进从右到左的功能组合 - 它适用于0,1或更多功能
def identity (x):
return x
def compose (f = identity, *gs):
if not gs:
return f
else:
return lambda x: f (compose (*gs) (x))
def double (x):
return x * 2
def add1 (x):
return x + 1
# identity (5)
compose () (5) # 5
# print (5)
compose (print) (5) # 5
# print (add1 (5))
compose (print, add1) (5) # 6
# print (add1 (double (5)))
compose (print, add1, double) (5) # 11
# print (add1 (double (double (5))))
compose (print, add1, double, double) (5) # 21
要使其支持可变参数,只需更新lambda - 粗体
中的更改def identity (x):
return x
def compose (f = identity, *gs):
if not gs:
return f
else:
return lambda *xs: f (compose (*gs) (*xs))
def mult (x,y):
return x * y
def double (x):
return mult (2, x)
# print (double (double (mult (2, 3))))
compose (print, double, double, mult) (2,3) # 24