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

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

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


当前回答

你说的是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函数。我花了一段时间来适应它们,但最终我明白了它们是语言中非常有价值的一部分。

其他回答

你说的是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函数。我花了一段时间来适应它们,但最终我明白了它们是语言中非常有价值的一部分。

我怀疑lambda不会消失。 请参阅Guido关于最终放弃尝试删除它的帖子。也请参阅冲突概要。

你可以看看这篇文章,了解更多Python函数特性背后的交易历史: http://python-history.blogspot.com/2009/04/origins-of-pythons-functional-features.html

奇怪的是,最初引入lambda和其他函数特性的map、filter和reduce函数在很大程度上已经被列表推导式和生成器表达式所取代。事实上,在Python 3.0中,reduce函数已从内置函数列表中删除。(但是,没有必要投诉lambda、map或filter的删除:它们被保留了。: -)

我个人的意见是:就清晰度而言,lambda值不了多少。通常有一个更清晰的不包含的解。

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

下面是一些例子:

实现空对象模式:

{
    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()

首先恭喜你算出了。在我看来,这是一个非常强大的构念。如今函数式编程语言的发展趋势无疑表明,在不久的将来,它既不应该被避免,也不会被重新定义。

你只需要换个角度思考。我相信你很快就会爱上它的。但是如果你只和python打交道要小心。因为lambda不是一个真正的闭包,它以某种方式“坏了”:python的lambda坏了

在我看来,lambda的一个好处是,它可以将简单表单的计算推迟到需要值时才进行。让我解释一下。

许多库例程的实现使得它们允许某些参数被调用(lambda是其中之一)。其思想是,实际值只在将要使用它的时候计算(而不是在调用它的时候)。一个(虚构的)例子可能有助于说明这一点。假设你有一个程序,它将记录一个给定的时间戳。您希望例程使用当前时间减去30分钟。你会这么说的

log_timestamp(datetime.datetime.now() - datetime.timedelta(minutes = 30))

现在假设实际函数只在某个事件发生时才被调用,并且您希望仅在该事件发生时计算时间戳。你可以这样做

log_timestamp(lambda : datetime.datetime.now() - datetime.timedelta(minutes = 30))

假设log_timestamp可以像这样处理可调用对象,它将在需要时计算这个值,届时您将获得时间戳。

当然,还有其他方法可以做到这一点(例如使用operator模块),但我希望我已经传达了这一点。

更新:这里有一个更具体的现实世界的例子。

更新2:我认为这是所谓的“坦克”的一个例子。