如何创建一个函数,将一个函数应用于 Python 中另一个函数的输入?
How to create a function that applies a function to the inputs of another function in Python?
我正在寻找一种实用的方法来执行以下操作:
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
这似乎与柯里化有关,但我能找到的所有示例都使用只有一个输入变量的函数。我想要这样的东西:
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
.
根据您需要的可扩展性,另一种方法是创建一个对象来实现您的运算符方法,每个 return 相同的对象,允许您以任意顺序将运算符链接在一起.
如果你总是能应付 return 列出一个列表,你也许能够让它发挥作用。
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)
。这需要稍微破解 Matthias 的建议。这个想法是为了获得一些关于要组成的函数的数量(args 的数量)的提示。由于 inspect
模块,这些信息是通过一些内省获得的。考虑到这一点,我们调整了参数通过函数链传递的方式。这里的主要假设是我们处理数学意义上的实函数,即函数返回一个浮点数,并至少接受一个参数。
from functools import reduce
from inspect import getfullargspec
def arity_one(func):
spec = getfullargspec(func)
return len(spec[0])==1 and spec[1] is None
def add(*args):
return reduce(lambda x,y:x+y, args, 0)
def neg(x):
return -x
def compose(fun1,fun2):
def comp(*args):
if arity_one(fun2): return fun1(*(map( fun2, args)))
else: return fun1(fun2(*args))
return comp
neg_add = compose(neg, add)
add_neg = compose(add, neg)
print(f"-2+(-3) = {add_neg(2, 3)}")
print(f"-(2+3) = {neg_add(2, 3)}")
解决方案还是很临时的...
我正在寻找一种实用的方法来执行以下操作:
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
这似乎与柯里化有关,但我能找到的所有示例都使用只有一个输入变量的函数。我想要这样的东西:
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
.
根据您需要的可扩展性,另一种方法是创建一个对象来实现您的运算符方法,每个 return 相同的对象,允许您以任意顺序将运算符链接在一起.
如果你总是能应付 return 列出一个列表,你也许能够让它发挥作用。
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)
。这需要稍微破解 Matthias 的建议。这个想法是为了获得一些关于要组成的函数的数量(args 的数量)的提示。由于 inspect
模块,这些信息是通过一些内省获得的。考虑到这一点,我们调整了参数通过函数链传递的方式。这里的主要假设是我们处理数学意义上的实函数,即函数返回一个浮点数,并至少接受一个参数。
from functools import reduce
from inspect import getfullargspec
def arity_one(func):
spec = getfullargspec(func)
return len(spec[0])==1 and spec[1] is None
def add(*args):
return reduce(lambda x,y:x+y, args, 0)
def neg(x):
return -x
def compose(fun1,fun2):
def comp(*args):
if arity_one(fun2): return fun1(*(map( fun2, args)))
else: return fun1(fun2(*args))
return comp
neg_add = compose(neg, add)
add_neg = compose(add, neg)
print(f"-2+(-3) = {add_neg(2, 3)}")
print(f"-(2+3) = {neg_add(2, 3)}")
解决方案还是很临时的...