我在试着找出Python的lambda。lambda是那些在现实生活中应该被遗忘的“有趣”语言项之一吗?
我确信有一些边缘情况可能需要它,但是考虑到它的模糊性,它在未来版本中被重新定义的可能性(我基于它的各种定义的假设)以及降低的编码清晰度——应该避免它吗?
这让我想起了C类型的溢出(缓冲区溢出)——指向顶部变量并重载以设置其他字段值。这感觉有点像技术人员的表演,但维护程序员的噩梦。
我在试着找出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函数。我花了一段时间来适应它们,但最终我明白了它们是语言中非常有价值的一部分。
其他回答
我是一个python初学者,所以为了获得一个清晰的lambda概念,我将它与'for'循环进行了比较;在效率方面。 下面是代码(python 2.7) -
import time
start = time.time() # Measure the time taken for execution
def first():
squares = map(lambda x: x**2, range(10))
# ^ Lambda
end = time.time()
elapsed = end - start
print elapsed + ' seconds'
return elapsed # gives 0.0 seconds
def second():
lst = []
for i in range(10):
lst.append(i**2)
# ^ a 'for' loop
end = time.time()
elapsed = end - start
print elapsed + ' seconds'
return elapsed # gives 0.0019998550415 seconds.
print abs(second() - first()) # Gives 0.0019998550415 seconds!(duh)
我使用lambdas来避免代码重复。这样函数就容易理解了 例如:
def a_func()
...
if some_conditon:
...
call_some_big_func(arg1, arg2, arg3, arg4...)
else
...
call_some_big_func(arg1, arg2, arg3, arg4...)
我用一个临时变量替换它
def a_func()
...
call_big_f = lambda args_that_change: call_some_big_func(arg1, arg2, arg3, args_that_change)
if some_conditon:
...
call_big_f(argX)
else
...
call_big_f(argY)
两行总结:
闭包:非常有用。学习它们,利用它们,热爱它们。 Python的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——这花了我一段时间才弄明白。
请注意,这不是对任何事情的谴责。每个人都有不容易得到的东西。
lambda是那些在现实生活中应该被遗忘的“有趣”语言项目之一吗?
No.
我相信有一些边缘情况可能需要它,但考虑到它的模糊性,
它并不晦涩。在我过去工作过的两个团队中,每个人都一直在使用这个功能。
它在未来版本中被重新定义的可能性(我基于它的各种定义的假设)
除了几年前修复闭包语义之外,我还没有看到在Python中重新定义它的严肃建议。
编码清晰度的降低——应该避免吗?
如果你用对了,也不会不太清楚。相反,拥有更多可用的语言结构可以增加清晰度。
这让我想起了C类型的溢出(缓冲区溢出)——指向顶部变量并重载以设置其他字段值……有点像技术人员的表演技巧,但维护程序员的噩梦。
就像缓冲区溢出?哇。如果您认为lambda是一个“维护噩梦”,我无法想象您将如何使用它。