我在试着找出Python的lambda。lambda是那些在现实生活中应该被遗忘的“有趣”语言项之一吗?

我确信有一些边缘情况可能需要它,但是考虑到它的模糊性,它在未来版本中被重新定义的可能性(我基于它的各种定义的假设)以及降低的编码清晰度——应该避免它吗?

这让我想起了C类型的溢出(缓冲区溢出)——指向顶部变量并重载以设置其他字段值。这感觉有点像技术人员的表演,但维护程序员的噩梦。


当前回答

在Python中,lambda只是内联定义函数的一种方式,

a = lambda x: x + 1
print a(1)

和. .

def a(x): return x + 1
print a(1)

..是完全一样的。

你可以用lambda做任何常规函数做不到的事情——Python函数和其他任何东西一样都是对象,lambdas只是定义一个函数:

>>> a = lambda x: x + 1
>>> type(a)
<type 'function'>

老实说,我认为lambda关键字在python中是多余的——我从来没有需要使用它们(或者见过使用它们的地方,常规函数、列表理解或许多内置函数中的一个本可以更好地使用)。

对于一个完全随机的例子,摘自文章“Python的lambda被破坏了!”:

要查看lambda是如何被破坏的,请尝试生成一个函数fs=[f0,…,f9]其中fi(n)=i+n。第一次尝试: >>> fs = [(lambda n: I + n) for I in range(10)] > > > fs [3] (4) 13

我想说的是,即使这样确实有效,它也太可怕了,而且是“非python化的”,同样的功能可以用无数其他方式来编写,例如:

>>> n = 4
>>> [i + n for i in range(10)]
[4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

是的,这是不一样的,但我从未见过需要在列表中生成一组lambda函数的原因。这在其他语言中可能是有意义的,但Python不是Haskell(或Lisp,或…)

请注意,我们可以使用lambda,仍然可以达到预期的效果 结果如下: >>> fs = [(lambda n,i=i: i + n) for i in range(10)] > > > fs [3] (4) 7

编辑:

在一些情况下lambda是有用的,例如在PyQt应用程序中连接信号时,它通常很方便,像这样:

w = PyQt4.QtGui.QLineEdit()
w.textChanged.connect(lambda event: dothing())

只是执行w.textChanged.connect(dothing)将使用额外的事件参数调用dothing方法并导致错误。使用lambda意味着我们可以整齐地删除参数,而不必定义包装函数。

其他回答

两行总结:

闭包:非常有用。学习它们,利用它们,热爱它们。 Python的lambda关键字:不必要,偶尔有用。如果你发现自己在用它做任何复杂的事情,把它放在一边,定义一个真正的函数。

我发现lambda对于执行相同功能的函数列表很有用,但适用于不同的情况。

就像Mozilla的复数规则:

plural_rules = [
    lambda n: 'all',
    lambda n: 'singular' if n == 1 else 'plural',
    lambda n: 'singular' if 0 <= n <= 1 else 'plural',
    ...
]
# Call plural rule #1 with argument 4 to find out which sentence form to use.
plural_rule[1](4) # returns 'plural'

如果你必须为所有这些定义一个函数,到最后你会疯掉的。 另外,像plural_rule_1, plural_rule_2这样的函数名也不太好。当你依赖于变量函数id时,你需要eval()它。

我经常使用它,主要是作为空对象或将参数部分绑定到函数。

下面是一些例子:

实现空对象模式:

{
    DATA_PACKET: self.handle_data_packets
    NET_PACKET: self.handle_hardware_packets
}.get(packet_type, lambda x : None)(payload)

对于参数绑定:

假设我有以下API

def dump_hex(file, var)
    # some code
    pass

class X(object):
    #...
    def packet_received(data):
        # some kind of preprocessing
        self.callback(data)
    #...

然后,当我不想快速转储接收到的数据到一个文件,我这样做:

dump_file = file('hex_dump.txt','w')
X.callback = lambda (x): dump_hex(dump_file, x)
...
dump_file.close()

你可以用lambda做的任何事情,都可以用命名函数或列表和生成器表达式做得更好。

因此,在大多数情况下,在任何情况下您都应该只使用其中一种(可能除了在交互式解释器中编写的草稿代码)。

你说的是lambda表达式吗?就像

lambda x: x**2 + 2*x - 5

这些东西其实很有用。Python支持一种称为函数式编程的编程风格,在这种编程风格中,您可以将函数传递给其他函数来执行某些操作。例子:

mult3 = filter(lambda x: x % 3 == 0, [1, 2, 3, 4, 5, 6, 7, 8, 9])

将mult3设置为[3,6,9],即原始列表中3的倍数的元素。这句话更短(有人可能会说,更清楚)

def filterfunc(x):
    return x % 3 == 0
mult3 = filter(filterfunc, [1, 2, 3, 4, 5, 6, 7, 8, 9])

当然,在这个特殊的情况下,你可以做同样的事情作为一个列表推导:

mult3 = [x for x in [1, 2, 3, 4, 5, 6, 7, 8, 9] if x % 3 == 0]

(甚至作为range(3,10,3)),但还有许多其他更复杂的用例,在这些用例中,您不能使用列表推导式,lambda函数可能是写出一些东西的最短方法。

Returning a function from another function >>> def transform(n): ... return lambda x: x + n ... >>> f = transform(3) >>> f(4) 7 This is often used to create function wrappers, such as Python's decorators. Combining elements of an iterable sequence with reduce() >>> reduce(lambda a, b: '{}, {}'.format(a, b), [1, 2, 3, 4, 5, 6, 7, 8, 9]) '1, 2, 3, 4, 5, 6, 7, 8, 9' Sorting by an alternate key >>> sorted([1, 2, 3, 4, 5, 6, 7, 8, 9], key=lambda x: abs(5-x)) [5, 4, 6, 3, 7, 2, 8, 1, 9]

我经常使用lambda函数。我花了一段时间来适应它们,但最终我明白了它们是语言中非常有价值的一部分。