如何创建一个函数,将一个函数应用于Python中另一个函数的输入?
我正在寻找一种很好的功能性方法来执行以下操作:如何创建一个函数,将一个函数应用于Python中另一个函数的输入?,python,functional-programming,currying,Python,Functional Programming,Currying,我正在寻找一种很好的功能性方法来执行以下操作: def add(x, y): return x + y def neg(x): return -x def c(x, y): # Apply neg to inputs for add _x = neg(x) _y = neg(y) return add(_x, _y) neg_sum = c(2, 2) # -4 它似乎与curry有关,但我能找到的所有示例都使用只有一个输入变量的函数
def add(x, y):
return x + y
def neg(x):
return -x
def c(x, y):
# Apply neg to inputs for add
_x = neg(x)
_y = neg(y)
return add(_x, _y)
neg_sum = c(2, 2) # -4
它似乎与curry有关,但我能找到的所有示例都使用只有一个输入变量的函数。我想要这样的东西:
def add(x, y):
return x + y
def neg(x):
return -x
c = apply(neg, add)
neg_sum = c(2, 2) # -4
这是一种相当直接的方法:
def add(x, y):
return x + y
def neg(x):
return -x
def apply(g, f):
# h is a function that returns
# f(g(arg1), g(arg2), ...)
def h(*args):
return f(*map(g, args))
return h
# or this:
# def apply(g, f):
# return lambda *args: f(*map(g, args))
c = apply(neg, add)
neg_sum = c(2, 2) # -4
请注意,当在函数定义中将
*myvar
用作参数时,myvar
将成为接收到的所有非关键字参数的列表。如果使用*expression
作为参数调用函数,则expression
中的所有项都将解包并作为单独的参数发送给函数。我使用这两种行为使h
接受未知的参数列表,然后对每个参数应用函数g
(使用map
),然后将所有参数作为参数传递给f
,这是一种相当直接的方法:
def add(x, y):
return x + y
def neg(x):
return -x
def apply(g, f):
# h is a function that returns
# f(g(arg1), g(arg2), ...)
def h(*args):
return f(*map(g, args))
return h
# or this:
# def apply(g, f):
# return lambda *args: f(*map(g, args))
c = apply(neg, add)
neg_sum = c(2, 2) # -4
请注意,当在函数定义中将
*myvar
用作参数时,myvar
将成为接收到的所有非关键字参数的列表。如果使用*expression
作为参数调用函数,则expression
中的所有项都将解包并作为单独的参数发送给函数。我使用这两种行为使h
接受未知的参数列表,然后对每个参数应用函数g
(使用map
),然后将所有参数作为参数传递给f
一种不同的方法,这取决于您需要的扩展程度,是创建一个实现运算符方法的对象,每个方法返回相同的对象,允许您以任意顺序将运算符链接在一起
如果你能处理它总是返回一个列表,你也许能使它工作
class mathifier:
def __init__(self,values):
self.values = values
def neg(self):
self.values = [-value for value in self.values]
return self
def add(self):
self.values = [sum(self.values)]
return self
print (mathifier([2,3]).neg().add().values)
您仍然可以为任何一组链接函数获取命名函数:
neg_add = lambda x : mathifier(x).neg().add()
print(neg_add([2,3]).values)
另一种不同的方法是创建一个实现操作符方法的对象,每个操作符方法返回相同的对象,允许您以任意顺序将操作符链接在一起,这取决于您需要的扩展程度 如果你能处理它总是返回一个列表,你也许能使它工作
class mathifier:
def __init__(self,values):
self.values = values
def neg(self):
self.values = [-value for value in self.values]
return self
def add(self):
self.values = [sum(self.values)]
return self
print (mathifier([2,3]).neg().add().values)
您仍然可以为任何一组链接函数获取命名函数:
neg_add = lambda x : mathifier(x).neg().add()
print(neg_add([2,3]).values)
从Matthias Fripp的回答中,我问自己:我想以两种方式撰写
add
和neg
:add_neg(*args)
和neg_add(*args)
。这需要对马提亚的建议稍加修改。这样做的目的是获得一些关于要组合的函数的arity(参数的数量)的提示。借助inspect
模块,您可以通过一点内省获得此信息。考虑到这一点,我们调整参数通过func链的方式。这里的主要假设是,我们处理的是数学意义上的实函数,即返回一个浮点数的函数,并且至少取一个参数
从functools导入reduce
从检查导入getfullargspec
定义一(功能):
spec=getfullargspec(func)
返回len(spec[0])==1,spec[1]为无
def add(*args):
返回减少值(λx,y:x+y,args,0)
def neg(x):
返回-x
def组合(fun1、fun2):
def组件(*参数):
if arity_one(fun2):返回fun1(*(map(fun2,args)))
其他:返回fun1(fun2(*args))
回报补偿
neg_add=compose(neg,add)
add_neg=compose(add,neg)
打印(f)-2+(-3)={add_neg(2,3)}”)
印刷品(f“-(2+3)={neg_add(2,3)}”)
解决方案仍然是非常临时的…从Matthias Fripp的回答中,我问自己:我想以两种方式撰写
add
和neg
:add_neg(*args)
和neg_add(*args)
。这需要对马提亚的建议稍加修改。这样做的目的是获得一些关于要组合的函数的arity(参数的数量)的提示。借助inspect
模块,您可以通过一点内省获得此信息。考虑到这一点,我们调整参数通过func链的方式。这里的主要假设是,我们处理的是数学意义上的实函数,即返回一个浮点数的函数,并且至少取一个参数
从functools导入reduce
从检查导入getfullargspec
定义一(功能):
spec=getfullargspec(func)
返回len(spec[0])==1,spec[1]为无
def add(*args):
返回减少值(λx,y:x+y,args,0)
def neg(x):
返回-x
def组合(fun1、fun2):
def组件(*参数):
if arity_one(fun2):返回fun1(*(map(fun2,args)))
其他:返回fun1(fun2(*args))
回报补偿
neg_add=compose(neg,add)
add_neg=compose(add,neg)
打印(f)-2+(-3)={add_neg(2,3)}”)
印刷品(f“-(2+3)={neg_add(2,3)}”)
解决方案仍然是非常临时的…您希望apply(g,f)
创建一个新函数c
,将函数g
应用于其所有参数,然后将结果传递给函数f
。这假设函数c
和f
接受相同数量的参数(可能有多个),并且c
和f
都返回一个值。是这样吗?我觉得可能还有其他一些情况,你想要构造f(g(h(x)),g(h(y))
或h(f(g(x),g(y)))
,这可能没有足够的对称性。或者,如果您只需多次调用apply
,有时使用单参数函数,它可能会这样做。您希望apply(g,f)
创建一个新函数c
,将函数g
应用于其所有参数,然后将结果传递给函数f
。这假设函数c
和f
接受相同数量的参数(可能有多个),并且c
和f
都返回一个值。是这样吗?我觉得可能还有其他一些情况