为什么使用 lambda 函数?
我可以找到很多东西,向我展示什么是 lambda 函数,以及语法如何工作以及不工作。但除了“酷因素”(我可以在调用另一个函数的过程中调用一个函数,这太棒了!)我还没有看到什么东西能够压倒性地说明为什么我真正需要/想要使用它们。
在我见过的大多数例子中,这似乎更多是一种风格或结构的选择。有点打破了Python规则中的“只有一种正确的方法来做某事”。它如何使我的程序更正确、更可靠、更快或更容易理解? (我见过的大多数编码标准都倾向于告诉您避免在一行上出现过于复杂的语句。如果这样更容易阅读,请将其分解。)
I can find lots of stuff showing me what a lambda function is, and how the syntax works and what not. But other than the "coolness factor" (I can make a function in middle a call to another function, neat!) I haven't seen something that's overwelmingly compelling to say why I really need/want to use them.
It seems to be more of a stylistic or structual choice in most examples I've seen. And kinda breaks the "Only one correct way to do something" in python rule. How does it make my programs, more correct, more reliable, faster, or easier to understand? (Most coding standards I've seen tend to tell you to avoid overly complex statements on a single line. If it makes it easier to read break it up.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
这是一个很好的例子:
与
从另一个角度来看: Lambda 表达式也称为“匿名函数”,在某些编程范式中非常有用,特别是函数式编程,而 lambda 演算为此提供了灵感。
http://en.wikipedia.org/wiki/Lambda_calculus
Here's a good example:
versus
From another angle: Lambda expressions are also known as "anonymous functions", and are very useful in certain programming paradigms, particularly functional programming, which lambda calculus provided the inspiration for.
http://en.wikipedia.org/wiki/Lambda_calculus
在某些情况下,语法更加简洁,主要是在处理
map
等时。对我来说似乎比:
我认为在这种情况下 lambda 是更好的选择,因为
def double
似乎几乎与使用它的map
断开连接。另外,我想它还有一个额外的好处,就是当你完成后,该函数就会被丢弃。在我看来,lambda 的一个缺点限制了它在 Python 中的实用性:lambda 只能有一个表达式(即不能有多行)。它无法在强制使用空格的语言中工作。
另外,每当我使用 lambda 时,我都感觉棒极了。
The syntax is more concise in certain situations, mostly when dealing with
map
et al.seems better to me than:
I think the lambda is a better choice in this situation because the
def double
seems almost disconnected from themap
that is using it. Plus, I guess it has the added benefit that the function gets thrown away when you are done.There is one downside to lambda which limits its usefulness in Python, in my opinion: lambdas can have only one expression (i.e., you can't have multiple lines). It just can't work in a language that forces whitespace.
Plus, whenever I use lambda I feel awesome.
对我来说,这是代码的表达能力的问题。当编写人们必须支持的代码时,该代码应该以尽可能简洁且易于理解的方式讲述一个故事。有时 lambda 表达式更复杂,有时它更直接地告诉该行或代码块正在做什么。写作时要运用判断力。
把它想象成构造一个句子。重要的部分是什么(名词和动词与对象和方法等)以及该行或代码块应该如何排序它们以直观地传达其正在执行的操作。
For me it's a matter of the expressiveness of the code. When writing code that people will have to support, that code should tell a story in as concise and easy to understand manner as possible. Sometimes the lambda expression is more complicated, other times it more directly tells what that line or block of code is doing. Use judgment when writing.
Think of it like structuring a sentence. What are the important parts (nouns and verbs vs. objects and methods, etc.) and how should they be ordered for that line or block of code to convey what it's doing intuitively.
Lambda 函数在回调函数或需要一次性函数的地方最有用。 JAB 的示例非常完美 - 最好附有关键字参数
key
,但它仍然提供有用的信息。当
出现距离
key 300行的时候有什么作用?确实没有任何迹象。您可能会有某种猜测,特别是如果您熟悉该函数,但通常需要回过头来查看。 OTOH,
告诉你更多。
可能还有更多信息,但仅通过使用匿名 lambda 函数而不是命名函数就可以获得大量信息。
另外,它不会污染您的命名空间;)
Lambda functions are most useful in things like callback functions, or places in which you need a throwaway function. JAB's example is perfect - It would be better accompanied by the keyword argument
key
, but it still provides useful information.When
appears 300 lines away from
what does key do? There's really no indication. You might have some sort of guess, especially if you're familiar with the function, but usually it requires going back to look. OTOH,
tells you a lot more.
There's probably some more information, but already that's a tremendous amount that you get just by using an anonymous lambda function instead of a named function.
Plus it doesn't pollute your namespace ;)
是的,你是对的——这是一个结构性的选择。仅使用 lambda 表达式可能不会使您的程序更加正确。它也不会让它们变得更可靠,这与速度无关。
这只是关于灵活性和表达能力。就像列表理解一样。您可以完成大部分定义命名函数的工作(可能会污染命名空间,但这又是纯粹的风格问题)。
它可以帮助提高可读性,因为您不必定义单独的命名函数,其他人必须找到、阅读和理解它所做的只是在其参数上调用方法 blah() 。
当您使用它来编写创建和返回其他函数的函数时,这可能会更有趣,这些函数到底做什么,取决于它们的参数。这可能是参数化代码行为的一种非常简洁且可读的方式。你可以表达更多有趣的想法。
但这仍然是一个结构性选择。否则你也可以这样做。但面向对象编程也是如此;)
Yes, you're right — it is a structural choice. It probably does not make your programs more correct by just using lambda expressions. Nor does it make them more reliable, and this has nothing to do with speed.
It is only about flexibility and the power of expression. Like list comprehension. You can do most of that defining named functions (possibly polluting namespace, but that's again purely stylistic issue).
It can aid to readability by the fact, that you do not have to define a separate named function, that someone else will have to find, read and understand that all it does is to call a method blah() on its argument.
It may be much more interesting when you use it to write functions that create and return other functions, where what exactly those functions do, depends on their arguments. This may be a very concise and readable way of parameterizing your code behaviour. You can just express more interesting ideas.
But that is still a structural choice. You can do that otherwise. But the same goes for object oriented programming ;)
Lambda 虽然在某些情况下很有用,但也有很大的滥用可能性。 lambda 几乎总是使代码更难以阅读。虽然将所有代码都放在一行中可能会让人感到满意,但对于下一个必须阅读您的代码的人来说,这会很糟糕。
直接来自 PEP8
“Guido 的主要见解之一是,代码的读取次数远多于编写次数。”
Lambda, while useful in certain situations, has a large potential for abuse. lambda's almost always make code more difficult to read. And while it might feel satisfying to fit all your code onto a single line, it will suck for the next person who has to read your code.
Direct from PEP8
"One of Guido's key insights is that code is read much more often than it is written."
暂时忽略我们正在讨论的具体匿名函数的细节。函数(包括匿名函数)在 Python 中是可赋值的量(几乎是值,但不是真正的值)。像这样的表达式
明确提到了四个匿名量:-1、0、10 和 lambda 运算符的结果,以及
map
调用的隐含结果。在某些语言中可以创建匿名类型的值。所以忽略函数和数字之间的表面差异。何时使用匿名函数而不是命名函数的问题类似于何时在代码中放置裸数字文字以及何时声明TIMES_I_WISHED_I_HAD_A_PONY
或BUFFER_SIZE 事先。有时使用(数字、字符串或函数)文字是合适的,有时命名这样的事物并通过其名称引用它更合适。
参见例如。 Allen Holub 的一本关于 Java 设计模式的具有挑衅性、发人深思或愤怒的书;他经常使用匿名类。
Ignore for a moment the detail that it's specifically anonymous functions we're talking about. functions, including anonymous ones, are assignable quantities (almost, but not really, values) in Python. an expression like
explicitly mentions four anonymous quantities: -1, 0, 10 and the result of the lambda operator, plus the implied result of the
map
call. it's possible to create values of anonymous types in some languages. so ignore the superficial difference between functions and numbers. the question when to use an anonymous function as opposed to a named one is similar to a question of when to put a naked number literal in the code and when to declare aTIMES_I_WISHED_I_HAD_A_PONY
orBUFFER_SIZE
beforehand. there are times when it's appropriate to use a (numeric, string or function) literal, and there are times when it's more appropriate to name such a thing and refer to it through its name.see eg. Allen Holub's provocative, thought-or-anger-provoking book on Design Patterns in Java; he uses anonymous classes quite a bit.
毫无疑问,滥用 lambda 函数通常会导致糟糕且难以阅读的代码。另一方面,如果使用得当,则会起到相反的作用。这个线程中已经有很好的答案,但我遇到的一个例子是:
这种简化的情况可以用许多其他方式重写,而无需使用 lambda。尽管如此,我们仍然可以通过这个示例推断出 lambda 函数如何在可能更复杂的情况和函数中提高可读性和代码重用性。
It is definitely true that abusing lambda functions often leads to bad and hard-to-read code. On the other hand, when used accurately, it does the opposite. There are already great answers in this thread, but one example I have come across is:
This simplified case could be rewritten in many other ways without the use of lambda. Still, one can infer how lambda functions can increase readability and code reuse in perhaps more complex cases and functions with this example.
Lambda 是匿名函数(没有名称的函数),可以分配给变量或可以作为参数传递给另一个函数。当您需要一小段偶尔或仅运行一次的函数时,就会意识到 lambda 的用处。您可以在需要变量或另一个函数时编写几行代码,而不是在全局范围内编写函数或将其作为主程序的一部分。此外,当您在函数调用期间将函数作为参数传递给另一个函数时,您可以更改参数(匿名函数),使函数本身成为动态的。假设如果匿名函数使用其范围之外的变量,则称为闭包。这在回调函数中很有用。
Lambdas are anonymous functions (function with no name) that can be assigned to a variable or that can be passed as an argument to another function. The usefulness of lambda will be realized when you need a small piece of function that will be run once in a while or just once. Instead of writing the function in global scope or including it as part of your main program you can toss around few lines of code when needed to a variable or another function. Also when you pass the function as an argument to another function during the function call you can change the argument (the anonymous function) making the function itself dynamic. Suppose if the anonymous function uses variables outside its scope it is called closure. This is useful in callback functions.
我学到的 lambda 函数的一种用法是,没有其他好的替代方法,或者至少对我来说最好的是作为函数参数中的默认操作,
这会返回没有更改的值,但您可以选择提供一个函数来执行转换或操作(例如打印答案,而不仅仅是返回)
通常在排序时用作键很有用:
其效果是按顺序按每个项目的第(从零开始的记住)元素进行排序。对于逆向,你不需要 lambda,因为它使用起来更清晰。
通常,创建新的实数函数并使用它而不是 lambda 几乎同样容易。如果人们研究了很多 Lisp 或其他函数式编程,他们也会自然地倾向于使用 lambda 函数,因为在 Lisp 中函数定义是由 lambda 演算处理的。
One use of lambda function which I have learned, and where is not other good alternative or at least looks for me best is as default action in function parameter by
This returns the value without change, but you can supply one function optionally to perform a transformation or action (like printing the answer, not only returning)
Also often it is useful to use in sorting as key:
The effect is to sort by fieldth (zero based remember) element of each item in sequence. For reversing you do not need lambda as it is clearer to use
Often it is almost as easy to do new real function and use that instead of lambda. If people has studied much Lisp or other functional programming, they also have natural tendency to use lambda function as in Lisp the function definitions are handled by lambda calculus.
Lambda 是对象,而不是方法,并且不能以与方法相同的方式调用它们。
例如
succ mow 持有一个 Proc 对象,我们可以像其他任何对象一样使用它:
给我们一个输出 = 3
Lambdas are objects, not methods, and they cannot be invoked in the same way that methods are.
for e.g
succ mow holds a Proc object, which we can use like any other:
gives us an output = 3
我想指出除列表处理之外的一种情况,其中 lambda 函数似乎是最佳选择:
如果我们在此处删除 lambda 函数,回调可能只会执行一次回调。
I want to point out one situation other than list-processing where the lambda functions seems the best choice:
And if we drop lambda function here, the callback may only execute the callback once.
还有一点是python没有switch语句。将 lambda 表达式与 dict 结合起来可能是一种有效的替代方案。例如:
Another point is that python does not have switch statements. Combining lambdas with dicts can be an effective alternative. e.g.:
在某些情况下,用 lambda 来表达简单的东西会更清楚。例如,考虑常规排序与反向排序:
对于后一种情况,编写一个单独的成熟函数只是为了返回
-cmp(a, b)
会比 lambda 产生更多误解。In some cases it is much more clear to express something simple as a lambda. Consider regular sorting vs. reverse sorting for example:
For the latter case writing a separate full-fledged function just to return a
-cmp(a, b)
would create more misunderstanding then a lambda.Lambda 允许您即时创建函数。我见过的大多数示例只不过是创建一个函数,并在创建时而不是执行时传递参数。或者,它们通过在使用前不需要正式声明函数来简化代码。
一个更有趣的用途是动态构造一个 python 函数来计算直到运行时(用户输入)才知道的数学表达式。创建后,可以使用不同的参数重复调用该函数来计算表达式(假设您想绘制它)。考虑到 eval(),这甚至可能是一个糟糕的例子。这种类型的使用才是“真正”的力量所在 - 动态创建更复杂的代码,而不是您经常看到的简单示例,这些示例只不过是减少了(源)代码大小。
Lambdas allow you to create functions on the fly. Most of the examples I've seen don't do much more than create a function with parameters passed at the time of creation rather than execution. Or they simplify the code by not requiring a formal declaration of the function ahead of use.
A more interesting use would be to dynamically construct a python function to evaluate a mathematical expression that isn't known until run time (user input). Once created, that function can be called repeatedly with different arguments to evaluate the expression (say you wanted to plot it). That may even be a poor example given eval(). This type of use is where the "real" power is - in dynamically creating more complex code, rather than the simple examples you often see which are not much more than nice (source) code size reductions.
你掌握了 lambda,你就掌握了 python 中的快捷方式。原因如下:
这里我们可以看到列表理解的 4 个部分:
编辑:正如 juanpa 在评论中指出的那样,使用 x.extract().text 完全没问题,但重点是解释 lambda 管道的使用,即将 lambda1 的输出作为 lambda2 的输入传递。通过(lambda1 y:g(x))(lambda2 x:f(x))
you master lambda, you master shortcuts in python.Here is why:
here we can see 4 parts of the list comprehension:
Edit: as pointed out in the comments, by juanpa, its completely fine to use x.extract().text but the point was explaining the use of lambda pipe, ie passing the output of lambda1 as input to lambda2. via
(lambda1 y:g(x))(lambda2 x:f(x))