我遇到了一个非常聪明的小函数,它接受两个函数,在给定参数x
的情况下将它们叠加在一起:
def compose(f,g):
return lambda *x: f(g(*x))
现在我的问题在于*x
,因为我没有看到它在这里做了什么。为什么它不简单x
(没有星号)?
以下是我的测试:
>>> def compose(f,g):
... return lambda *x: f(g(*x))
...
>>> this = lambda i: i+1
>>> that = lambda b: b+1
>>> compose(this,that)(2)
4
>>> def compose(f,g):
... return lambda x: f(g(x))
...
>>> compose(this,that)(2)
4
>>> def compose(f,g):
... return lambda *x: f(g(*x))
...
>>> compose(this,that)(2,2)
TypeError: <lambda>() takes exactly 1 argument (2 given)
答案 0 :(得分:4)
如果g
(测试中that
)也可以使用可变数量的参数,那么lambda *x: f(g(*x))
可能会有用。
否则,不是那么多。
目的是允许使用任意数量的参数调用组合函数,并将所有这些参数传递给组合中的内部函数。
答案 1 :(得分:3)
为了补充@ Frederic的答案,如果compose
使用标准*args, **kwargs
construct,那将是最灵活的:
def compose(f,g):
return lambda *args, **kwargs: f(g(*args, **kwargs))
这样,compose
适用于任何g
函数,无论g
的签名如何。
您问题中的一个仅使用第一部分,即*args
,并使用不同的(非常规)名称*x
。
答案 2 :(得分:1)
您的测试的问题在于,您的作文函数this
和that
只接受一个参数,因此*
中的compose
点{1}}函数丢失(并且您收到&#34;正好采用1个参数&#34;错误)。
当你想传入解压缩的元组时,*
运算符的力量变得明显,而你的lambdas支持这个:
试试这个简单的地图缩小示例:
this = lambda *i: *[x**2 for x in i] # map tuple i
that = lambda *b: sum(b) # reduce tuple b
def compose(f,g):
return lambda *x: f(*g(*x))
compose(that,this)(2,2)