如何创建一个函数,将一个函数应用于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
都返回一个值。是这样吗?我觉得可能还有其他一些情况