lambda可以使用* args作为参数吗?

时间:2016-04-26 12:19:06

标签: python lambda

我正在使用lambda这样计算总和:

def my_func(*args):
    return reduce((lambda x, y: x + y), args)

my_func(1,2,3,4)

,其输出为10

但我想要一个lambda函数,它接受随机参数并对所有这些函数求和。假设这是一个lambda函数:

add = lambda *args://code for adding all of args

某人应该能够将add功能称为:

add(5)(10)          # it should output 15
add(1)(15)(20)(4)   # it should output 40

也就是说,一个人应该能够提供任意的 括号数。

这在Python中是否可行?

3 个答案:

答案 0 :(得分:11)

这对lambda来说是不可能的,但绝对可以做到这一点就是Python。

要实现此行为,您可以继承int并覆盖其__call__方法,以便每次都返回具有更新值的同一类的新实例:

class Add(int):
    def __call__(self, val):
        return type(self)(self + val)

<强>演示:

>>> Add(5)(10)
15
>>> Add(5)(10)(15)
30
>>> Add(5)
5
# Can be used to perform other arithmetic operations as well
>>> Add(5)(10)(15) * 100
3000

如果您想支持float,那么请从float而不是int继承。

答案 1 :(得分:3)

你正在寻找的那种“cur”“是不可能的。

想象一下add(5)(10)是15.在这种情况下,add(5)(10)(20)需要等同于15(20)。但是15不可调用,特别是与“add 15”操作不同。

您当然可以说lambda *args: sum(args),但您需要以通常的方式传递其参数:add(5,10,20,93)

[编辑添加:]有些语言以这种方式处理具有多个参数的函数;例如,哈斯克尔。但是那些具有多个参数的固定数量的函数,并且这样做的全部优点是,例如, add 3 4是7,然后add 3 是一个为事物添加3的函数 - 这正是您希望获取的行为,如果你想要这样的东西采取可变数量的参数。

对于固定arity的函数,你可以获得Haskell-ish行为,虽然语法在Python中不能很好地工作,只需嵌套lambdas:在add = lambda x: lambda y: x+y后你可以说add(3)(4)并得到7,或者你可以说add(3)并获得一个增加3的功能。

[EDITED再次添加:]正如Ashwini Chaudhary巧妙的回答所示,你实际上可以通过安排add(5)(10)不是实际的整数15来做你想做的事,而是另一个非常类似于15的对象(和将在大多数情况下显示为15)。对我来说,这绝对属于“你应该知道但从未实际做过的巧妙技巧”的类别,但如果你有一个真正需要这种行为的应用程序,那就是一种方法。

(为什么你不应该做这种事情?主要是因为它很脆弱并且容易在边缘情况下产生意想不到的结果。例如,如果你要求add(5)(10.5)会发生什么?这会因为AC而失败'方法; PM 2Ring的方法可以应付,但有不同的问题;例如,add(2)(3)==5将是False。避免这种事情的另一个原因是因为它巧妙而且相当模糊,因此可能会让其他人阅读你的代码感到困惑。这有多重要取决于还有谁会阅读你的代码。我应该补充一点,为了避免怀疑我很确定AC和PM2R很清楚这一点,我认为他们的答案非常聪明和优雅;我不批评他们,而是警告他们如何处理他们告诉你的事情。)

答案 2 :(得分:1)

你可以种类在课堂上这样做,但我真的不建议使用这个&#34;派对技巧&#34;在实际代码中。

class add(object):
    def __init__(self, arg):
        self.arg = arg

    def __call__(self, arg):
        self.arg += arg
        return self

    def __repr__(self):
        return repr(self.arg)

# Test
print(add(1)(15)(20)(4))    

<强>输出

40 

最初,add(1)创建add个实例,将其.args属性设置为1. add(1)(15)调用.call方法,将15添加到当前值.args并返回实例,以便我们再次调用它。对于后续调用重复相同的过程。最后,当实例传递给print时,会调用其__repr__方法,该方法将.args的字符串表示传递回print