我在试着找出Python的lambda。lambda是那些在现实生活中应该被遗忘的“有趣”语言项之一吗?
我确信有一些边缘情况可能需要它,但是考虑到它的模糊性,它在未来版本中被重新定义的可能性(我基于它的各种定义的假设)以及降低的编码清晰度——应该避免它吗?
这让我想起了C类型的溢出(缓冲区溢出)——指向顶部变量并重载以设置其他字段值。这感觉有点像技术人员的表演,但维护程序员的噩梦。
我在试着找出Python的lambda。lambda是那些在现实生活中应该被遗忘的“有趣”语言项之一吗?
我确信有一些边缘情况可能需要它,但是考虑到它的模糊性,它在未来版本中被重新定义的可能性(我基于它的各种定义的假设)以及降低的编码清晰度——应该避免它吗?
这让我想起了C类型的溢出(缓冲区溢出)——指向顶部变量并重载以设置其他字段值。这感觉有点像技术人员的表演,但维护程序员的噩梦。
当前回答
Lambdas实际上是非常强大的构造,它源于函数式编程的思想,而且在Python的近期内,它绝不可能被轻易地修改、重新定义或删除。它们可以帮助您编写更强大的代码,因为它允许您将函数作为参数传递,因此函数是一等公民。
Lambdas确实容易让人困惑,但一旦获得了扎实的理解,你就可以写出像这样干净优雅的代码:
squared = map(lambda x: x*x, [1, 2, 3, 4, 5])
上面的代码行返回列表中数字的平方的列表。当然,你也可以这样做:
def square(x):
return x*x
squared = map(square, [1, 2, 3, 4, 5])
显然,前一种代码更短,如果您打算只在一个地方使用map函数(或任何以函数作为参数的类似函数),则尤其如此。这也使代码更加直观和优雅。
另外,正如@David Zaslavsky在他的回答中提到的,列表推导并不总是正确的方法,尤其是当你的列表必须从一些晦涩的数学方法中获取值时。
从更实际的角度来看,lambdas最近对我来说最大的优势之一是在GUI和事件驱动编程方面。如果你看一下Tkinter中的回调,它们所接受的参数就是触发它们的事件。如。
def define_bindings(widget):
widget.bind("<Button-1>", do-something-cool)
def do-something-cool(event):
#Your code to execute on the event trigger
现在如果你有一些论点要通过呢?简单到传递2个参数来存储鼠标单击的坐标。你可以简单地这样做:
def main():
# define widgets and other imp stuff
x, y = None, None
widget.bind("<Button-1>", lambda event: do-something-cool(x, y))
def do-something-cool(event, x, y):
x = event.x
y = event.y
#Do other cool stuff
现在,您可以争辩说这可以使用全局变量来完成,但是,如果全局变量只用于一个特定的位置,您真的想要担心内存管理和泄漏吗?那只是糟糕的编程风格。
简而言之,lambdas是很棒的,永远不应该被低估。尽管Python lambdas与LISP lambdas不同(后者更强大),但您确实可以用它们做很多神奇的事情。
其他回答
你可以用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()它。
只是函数的一种奇特说法。除了它的名字,它没有什么晦涩、吓人或神秘的地方。当你读到下面这行,在脑海中用函数替换lambda:
>>> f = lambda x: x + 1
>>> f(3)
4
它只是定义了一个关于x的函数。其他一些语言,比如R,显式地说:
> f = function(x) { x + 1 }
> f(3)
4
你看到了什么?这是编程中最自然的事情之一。
我不能说python对lambda的具体实现,但一般来说lambda函数真的很方便。它们是函数式编程的核心技术(甚至是技术),在面向对象程序中也非常有用。对于某些类型的问题,它们是最好的解决方案,所以当然不应该忘记!
我建议你仔细阅读闭包和map函数(它链接到python文档,但它存在于几乎所有支持函数结构的语言中),看看它为什么有用。
函数这是一种非官僚化的创建函数的方法。
就是这样。例如,假设你有一个主要函数,需要对值平方。我们来看看传统的方法和的方法
传统的方法:
def main():
...
...
y = square(some_number)
...
return something
def square(x):
return x**2
方式:
def main():
...
square = lambda x: x**2
y = square(some_number)
return something
看到区别了吗?
Lambda函数非常适合用于列表,比如列表推导式或映射。事实上,列表理解是一种使用lambda来表达自己的“python”方式。例:
>>>a = [1,2,3,4]
>>>[x**2 for x in a]
[1,4,9,16]
让我们看看每个语法元素的含义:
[]:“给我一个清单” X **2:“使用这个新诞生的函数” 对于a中的x: "into each element in a"
很方便吧?创建这样的函数。让我们用lambda重写它:
>>> square = lambda x: x**2
>>> [square(s) for x in a]
[1,4,9,16]
现在让我们使用map,这是同样的东西,但更语言中立。Maps有两个参数:
(i)一个功能
(ii)可迭代对象
给你一个列表,其中每个元素它是应用于可迭代对象的每个元素的函数。
使用map,我们会得到:
>>> a = [1,2,3,4]
>>> squared_list = map(lambda x: x**2, a)
如果你掌握了lambdas和映射,你将拥有以简洁的方式操作数据的强大能力。Lambda函数既不晦涩,也不影响代码的清晰性。不要把难的东西和新东西混为一谈。一旦你开始使用它们,你就会发现非常清楚。