为什么Python Lambda有用?[关闭]

问题:为什么Python Lambda有用?[关闭]

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

我确定在某些情况下可能需要使用它,但是鉴于它的晦涩之处,在将来的版本中重新定义了它的潜力(根据各种定义我的假设)以及降低的编码清晰度-是否应该被避免?

这让我想起了C类型的溢出(缓冲区溢出)-指向顶部变量,并通过重载来设置其他字段值。感觉像是技术娴熟的演艺风格,但却是维护编码员的噩梦。

I’m trying to figure out Python lambdas. Is lambda one of those “interesting” language items that in real life should be forgotten?

I’m sure there are some edge cases where it might be needed, but given the obscurity of it, the potential of it being redefined in future releases (my assumption based on the various definitions of it) and the reduced coding clarity – should it be avoided?

This reminds me of overflowing (buffer overflow) of C types – pointing to the top variable and overloading to set the other field values. It feels like sort of a techie showmanship but maintenance coder nightmare.


回答 0

您是在谈论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函数可能是写出东西的最短方法。

  • 从另一个函数返回一个函数

    >>> def transform(n):
    ...     return lambda x: x + n
    ...
    >>> f = transform(3)
    >>> f(4)
    7

    这通常用于创建函数包装器,例如Python的装饰器。

  • 将可迭代序列的元素与 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'
  • 按备用键排序

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

Are you talking about lambda functions? Like

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

Those things are actually quite useful. Python supports a style of programming called functional programming where you can pass functions to other functions to do stuff. Example:

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

sets mult3 to [3, 6, 9], those elements of the original list that are multiples of 3. This is shorter (and, one could argue, clearer) than

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

Of course, in this particular case, you could do the same thing as a list comprehension:

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

(or even as range(3,10,3)), but there are many other, more sophisticated use cases where you can’t use a list comprehension and a lambda function may be the shortest way to write something out.

  • 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]
    

I use lambda functions on a regular basis. It took me a while to get used to them, but eventually I came to understand that they’re a very valuable part of the language.


回答 1

lambda只是一种幻想的表达方式function。除了它的名字,没有什么晦涩,令人生畏或神秘的东西。阅读以下行时,请以替换lambdafunction

>>> f = lambda x: x + 1
>>> f(3)
4

它只是定义的功能x。其他一些语言(如R)则明确指出:

> f = function(x) { x + 1 }
> f(3)
4

你看?这是编程中最自然的事情之一。

lambda is just a fancy way of saying function. Other than its name, there is nothing obscure, intimidating or cryptic about it. When you read the following line, replace lambda by function in your mind:

>>> f = lambda x: x + 1
>>> f(3)
4

It just defines a function of x. Some other languages, like R, say it explicitly:

> f = function(x) { x + 1 }
> f(3)
4

You see? It’s one of the most natural things to do in programming.


回答 2

两行摘要:

  1. 闭包:非常有用。学习他们,使用他们,爱他们。
  2. Python的lambda关键字:不必要,偶尔有用。如果您发现要使用它进行远程复杂的操作,则将其丢弃并定义一个真正的功能。

The two-line summary:

  1. Closures: Very useful. Learn them, use them, love them.
  2. Python’s lambda keyword: unnecessary, occasionally useful. If you find yourself doing anything remotely complex with it, put it away and define a real function.

回答 3

Lambda是非常重要的抽象机制的一部分,该机制处理高阶函数。为了正确理解其价值,请观看Abelson和Sussman的高质量类,并阅读SICP

这些是现代软件业务中的相关问题,并且变得越来越流行。

A lambda is part of a very important abstraction mechanism which deals with higher order functions. To get proper understanding of its value, please watch high quality lessons from Abelson and Sussman, and read the book SICP

These are relevant issues in modern software business, and becoming ever more popular.


回答 4

lambda在GUI编程中非常有用。例如,假设您要创建一组按钮,并且要使用单个参数化的回调,而不是每个按钮使用唯一的回调。Lambda可让您轻松实现:

for value in ["one","two","three"]:
    b = tk.Button(label=value, command=lambda arg=value: my_callback(arg))
    b.pack()

(注意:尽管这个问题是专门询问的lambda,但您也可以使用functools.partial获得相同类型的结果)

另一种方法是为每个按钮创建一个单独的回调,这可能导致代码重复。

lambdas are extremely useful in GUI programming. For example, lets say you’re creating a group of buttons and you want to use a single paramaterized callback rather than a unique callback per button. Lambda lets you accomplish that with ease:

for value in ["one","two","three"]:
    b = tk.Button(label=value, command=lambda arg=value: my_callback(arg))
    b.pack()

(Note: although this question is specifically asking about lambda, you can also use functools.partial to get the same type of result)

The alternative is to create a separate callback for each button which can lead to duplicated code.


回答 5

我怀疑lambda会消失。有关最终放弃尝试删除它的信息,请参见Guido的文章。另请参阅冲突概述

您可以查看此帖子,以获得有关Python功能特性背后交易的更多历史记录:http : //python-history.blogspot.com/2009/04/origins-of-pythons-functional-features.html

奇怪的是,最初促使引入lambda和其他功能特征的map,filter和reduce功能在很大程度上已被列表理解和生成器表达式所取代。实际上,reduce函数已从Python 3.0中的内置函数列表中删除。(但是,没有必要发送有关删除lambda,地图或过滤器的投诉:它们正在留下。:-)

我自己的2美分:就清晰程度而言,lambda很少值得。通常,有一个更清晰的解决方案,其中不包含lambda。

I doubt lambda will go away. See Guido’s post about finally giving up trying to remove it. Also see an outline of the conflict.

You might check out this post for more of a history about the deal behind Python’s functional features: http://python-history.blogspot.com/2009/04/origins-of-pythons-functional-features.html

Curiously, the map, filter, and reduce functions that originally motivated the introduction of lambda and other functional features have to a large extent been superseded by list comprehensions and generator expressions. In fact, the reduce function was removed from list of builtin functions in Python 3.0. (However, it’s not necessary to send in complaints about the removal of lambda, map or filter: they are staying. :-)

My own two cents: Rarely is lambda worth it as far as clarity goes. Generally there is a more clear solution that doesn’t include lambda.


回答 6

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

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

和..

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

..是完全一样的。

使用lambda不能执行任何操作,而使用常规函数则无法执行任何操作-在Python函数中,对象和其他函数一样,都是对象,而lambda只是定义一个函数:

>>> 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

我会争辩说,即使这样做确实可行,这也是可怕的和“非pythonic的”,可以用无数其他方式编写相同的功能,例如:

>>> 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带有额外event参数的方法,并导致错误。使用lambda意味着我们可以整齐地删除参数,而不必定义包装函数。

In Python, lambda is just a way of defining functions inline,

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

and..

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

..are the exact same.

There is nothing you can do with lambda which you cannot do with a regular function—in Python functions are an object just like anything else, and lambdas simply define a function:

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

I honestly think the lambda keyword is redundant in Python—I have never had the need to use them (or seen one used where a regular function, a list-comprehension or one of the many builtin functions could have been better used instead)

For a completely random example, from the article “Python’s lambda is broken!”:

To see how lambda is broken, try generating a list of functions fs=[f0,...,f9] where fi(n)=i+n. First attempt:

>>> fs = [(lambda n: i + n) for i in range(10)]
>>> fs[3](4)
13

I would argue, even if that did work, it’s horribly and “unpythonic”, the same functionality could be written in countless other ways, for example:

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

Yes, it’s not the same, but I have never seen a cause where generating a group of lambda functions in a list has been required. It might make sense in other languages, but Python is not Haskell (or Lisp, or …)

Please note that we can use lambda and still achieve the desired results in this way :

>>> fs = [(lambda n,i=i: i + n) for i in range(10)]
>>> fs[3](4)
7

Edit:

There are a few cases where lambda is useful, for example it’s often convenient when connecting up signals in PyQt applications, like this:

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

Just doing w.textChanged.connect(dothing) would call the dothing method with an extra event argument and cause an error. Using the lambda means we can tidily drop the argument without having to define a wrapping function.


回答 7

我发现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_1plural_rule_2等)也不是很好。而且eval(),当您依赖于可变函数id时就需要使用它。

I find lambda useful for a list of functions that do the same, but for different circumstances.

Like the Mozilla plural rules:

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'

If you’d have to define a function for all of those you’d go mad by the end of it.
Also, it wouldn’t be nice with function names like plural_rule_1, plural_rule_2, etc. And you’d need to eval() it when you’re depending on a variable function id.


回答 8

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

因此,在大多数情况下,您基本上只应该是在任何情况下都可以选择的一种(可能不是交互式解释器中编写的草稿代码)。

Pretty much anything you can do with lambda you can do better with either named functions or list and generator expressions.

Consequently, for the most part you should just one of those in basically any situation (except maybe for scratch code written in the interactive interpreter).


回答 9

我已经使用Python几年了,但从未遇到过需要 lambda的情况。确实,如本教程所述,它仅用于语法糖。

I’ve been using Python for a few years and I’ve never run in to a case where I’ve needed lambda. Really, as the tutorial states, it’s just for syntactic sugar.


回答 10

我不能说python的lambda的特定实现,但是总的来说lambda函数确实很方便。它们是函数式编程的核心技术(甚至是THE技术),在面向对象的程序中也很有用。对于某些类型的问题,它们是最好的解决方案,因此绝对不应忘记!

我建议您阅读闭包map函数(链接到python文档,但几乎所有支持功能构造的语言都存在),以了解其有用性。

I can’t speak to python’s particular implementation of lambda, but in general lambda functions are really handy. They’re a core technique (maybe even THE technique) of functional programming, and they’re also very useuful in object-oriented programs. For certain types of problems, they’re the best solution, so certainly shouldn’t be forgotten!

I suggest you read up on closures and the map function (that links to python docs, but it exists in nearly every language that supports functional constructs) to see why it’s useful.


回答 11

Lambda函数是创建函数的非官僚方式。

而已。例如,让我们假设您具有主要功能并且需要对值进行平方。让我们看看传统的方法和lambda方法:

传统方式:

def main():
...
...
y = square(some_number)
...
return something

def square(x):
    return x**2

Lambda方法:

def main():
...
square = lambda x: x**2
y = square(some_number)
return something

看到不同?

Lambda函数非常适合列表,例如列表推导或映射。实际上,列表理解是使用lambda表达自己的一种“ pythonic”方式。例如:

>>>a = [1,2,3,4]
>>>[x**2 for x in a]
[1,4,9,16]

让我们看看语法的每个元素的含义:

[]:“给我一个清单”

x ** 2:“使用此新生函数”

对于a中的x:“放入a中的每个元素”

方便吗?创建这样的功能。让我们使用lambda重写它:

>>> square = lambda x: x**2
>>> [square(s) for x in a]
[1,4,9,16]

现在让我们使用地图,这是一回事,但是在语言上是中立的。地图采用2个参数:

(i)一个功能

(ii)可迭代

并为您提供一个列表,其中每个元素都是应用于可迭代元素的函数。

因此,使用map我们将拥有:

>>> a = [1,2,3,4]
>>> squared_list = map(lambda x: x**2, a)

如果您掌握lambda和映射,那么您将拥有以简洁的方式操作数据的强大能力。Lambda函数既不模糊也不使代码清晰。不要将困难与新事物混淆。一旦开始使用它们,您会发现它非常清晰。

Lambda function it’s a non-bureaucratic way to create a function.

That’s it. For example, let’s supose you have your main function and need to square values. Let’s see the traditional way and the lambda way to do this:

Traditional way:

def main():
...
...
y = square(some_number)
...
return something

def square(x):
    return x**2

The lambda way:

def main():
...
square = lambda x: x**2
y = square(some_number)
return something

See the difference?

Lambda functions go very well with lists, like lists comprehensions or map. In fact, list comprehension it’s a “pythonic” way to express yourself using lambda. Ex:

>>>a = [1,2,3,4]
>>>[x**2 for x in a]
[1,4,9,16]

Let’s see what each elements of the syntax means:

[] : “Give me a list”

x**2 : “using this new-born function”

for x in a: “into each element in a”

That’s convenient uh? Creating functions like this. Let’s rewrite it using lambda:

>>> square = lambda x: x**2
>>> [square(s) for x in a]
[1,4,9,16]

Now let’s use map, which is the same thing, but more language-neutral. Maps takes 2 arguments:

(i) one function

(ii) an iterable

And gives you a list where each element it’s the function applied to each element of the iterable.

So, using map we would have:

>>> a = [1,2,3,4]
>>> squared_list = map(lambda x: x**2, a)

If you master lambdas and mapping, you will have a great power to manipulate data and in a concise way. Lambda functions are neither obscure nor take away code clarity. Don’t confuse something hard with something new. Once you start using them, you will find it very clear.


回答 12

lambda在我看来,其中的一件好事被低估了,它是将简单形式的评估推迟到需要该值之前的一种方式。让我解释。

实现了许多库例程,以便它们允许某些参数是可调用的(lambda是其中的一个)。想法是,仅在将要使用实际值时(而不是在调用它时)才计算实际值。一个(人为的)示例可能有助于说明这一点。假设您有一个要记录给定时间戳记的例程。您希望例程使用当前时间减去30分钟。你会这样称呼它

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

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

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

假设log_timestampcan可以处理这样的可调用对象,它将在需要时对其进行评估,届时您将获得时间戳。

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

更新是一个更具体的现实示例。

更新2:我认为这是所谓的“ thunk”的示例。

One of the nice things about lambda that’s in my opinion understated is that it’s way of deferring an evaluation for simple forms till the value is needed. Let me explain.

Many library routines are implemented so that they allow certain parameters to be callables (of whom lambda is one). The idea is that the actual value will be computed only at the time when it’s going to be used (rather that when it’s called). An (contrived) example might help to illustrate the point. Suppose you have a routine which which was going to do log a given timestamp. You want the routine to use the current time minus 30 minutes. You’d call it like so

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

Now suppose the actual function is going to be called only when a certain event occurs and you want the timestamp to be computed only at that time. You can do this like so

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

Assuming the log_timestamp can handle callables like this, it will evaluate this when it needs it and you’ll get the timestamp at that time.

There are of course alternate ways to do this (using the operator module for example) but I hope I’ve conveyed the point.

Update: Here is a slightly more concrete real world example.

Update 2: I think this is an example of what is called a thunk.


回答 13

如上所述,Python中的lambda运算符定义了一个匿名函数,而在Python函数中则是闭包。重要的是不要将闭包的概念与运算符lambda混淆,后者只是语法上的美沙酮。

几年前,当我开始使用Python时,我经常使用lambda,认为它们很酷,而且很理解列表。但是,我编写并必须维护一个用Python编写的大型网站,其功能点约为数千个。我从经验中学到,lambda可以用它们进行原型制作,但是除了保存一些键调用(有时甚至不保存)之外,内联函数(命名为闭包)什么也没有提供。

基本上可以归结为以下几点:

  • 更容易阅读使用有意义的名称明确编写的软件。根据定义,匿名闭包不能具有有意义的名称,因为它们没有名称。出于某种原因,这种简洁似乎也感染了lambda参数,因此我们经常看到像lambda x:x + 1这样的示例
  • 更容易重用已命名的闭包,因为当有名称可以引用时,它们可以多次被名称引用。
  • 调试使用命名闭包而不是lambda的代码更容易,因为该名称将出现在回溯中以及错误周围。

这足以将它们四舍五入并将其转换为命名的闭包。但是,我对匿名关闭持另外两个怨恨。

第一个怨恨就是它们只是使语言混乱的另一个不必要的关键字。

第二个怨恨在范式层次上更深,也就是说,我不喜欢它们提倡一种函数式编程风格,因为这种风格比消息传递,面向对象或过程风格的灵活性差,因为lambda演算不是Turing- complete(幸运的是,在Python中,即使在lambda中,我们仍然可以突破该限制)。我觉得Lambda推广这种风格的原因是:

  • 有一个隐式的回报,即它们似乎“应该”是函数。

  • 它们是另一种更清晰,更易读,更可重用且更通用的机制:方法的状态隐藏机制。

我努力编写无lambda的Python,并删除可见的lambda。我认为如果没有lambda,Python会是一种更好的语言,但这只是我的观点。

As stated above, the lambda operator in Python defines an anonymous function, and in Python functions are closures. It is important not to confuse the concept of closures with the operator lambda, which is merely syntactic methadone for them.

When I started in Python a few years ago, I used lambdas a lot, thinking they were cool, along with list comprehensions. However, I wrote and have to maintain a big website written in Python, with on the order of several thousand function points. I’ve learnt from experience that lambdas might be OK to prototype things with, but offer nothing over inline functions (named closures) except for saving a few key-stokes, or sometimes not.

Basically this boils down to several points:

  • it is easier to read software that is explicitly written using meaningful names. Anonymous closures by definition cannot have a meaningful name, as they have no name. This brevity seems, for some reason, to also infect lambda parameters, hence we often see examples like lambda x: x+1
  • it is easier to reuse named closures, as they can be referred to by name more than once, when there is a name to refer to them by.
  • it is easier to debug code that is using named closures instead of lambdas, because the name will appear in tracebacks, and around the error.

That’s enough reason to round them up and convert them to named closures. However, I hold two other grudges against anonymous closures.

The first grudge is simply that they are just another unnecessary keyword cluttering up the language.

The second grudge is deeper and on the paradigm level, i.e. I do not like that they promote a functional-programming style, because that style is less flexible than the message passing, object oriented or procedural styles, because the lambda calculus is not Turing-complete (luckily in Python, we can still break out of that restriction even inside a lambda). The reasons I feel lambdas promote this style are:

  • There is an implicit return, i.e. they seem like they ‘should’ be functions.

  • They are an alternative state-hiding mechanism to another, more explicit, more readable, more reusable and more general mechanism: methods.

I try hard to write lambda-free Python, and remove lambdas on sight. I think Python would be a slightly better language without lambdas, but that’s just my opinion.


回答 14

Lambda实际上是非常强大的构造,其源于函数式编程的思想,并且在不久的将来Python绝不会轻易对其进行修改,重新定义或删除。它们可以帮助您编写功能更强大的代码,因为它允许您将函数作为参数进行传递,从而使函数成为一流公民。

Lambda的确容易引起混淆,但是一旦获得了扎实的理解,您就可以编写干净的优雅代码,如下所示:

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在他的回答中提到的那样,列表理解并非总是可行的,特别是如果您的列表必须从某种晦涩的数学方法中获取值。

从更实际的角度来看,lambda的最大优点之一对我来说是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

现在您可以争辩说可以使用全局变量来完成此操作,但是您是否真的想担心内存管理和泄漏,特别是如果全局变量仅在一个特定的地方使用时呢?那将是糟糕的编程风格。

简而言之,lambda非常棒,绝对不能低估它。尽管Python Lambda与LISP Lambda(功能更强大)不同,但是您确实可以用它们做很多神奇的事情。

Lambdas are actually very powerful constructs that stem from ideas in functional programming, and it is something that by no means will be easily revised, redefined or removed in the near future of Python. They help you write code that is more powerful as it allows you to pass functions as parameters, thus the idea of functions as first-class citizens.

Lambdas do tend to get confusing, but once a solid understanding is obtained, you can write clean elegant code like this:

squared = map(lambda x: x*x, [1, 2, 3, 4, 5])

The above line of code returns a list of the squares of the numbers in the list. Ofcourse, you could also do it like:

def square(x):
    return x*x

squared = map(square, [1, 2, 3, 4, 5])

It is obvious the former code is shorter, and this is especially true if you intend to use the map function (or any similar function that takes a function as a parameter) in only one place. This also makes the code more intuitive and elegant.

Also, as @David Zaslavsky mentioned in his answer, list comprehensions are not always the way to go especially if your list has to get values from some obscure mathematical way.

From a more practical standpoint, one of the biggest advantages of lambdas for me recently has been in GUI and event-driven programming. If you take a look at callbacks in Tkinter, all they take as arguments are the event that triggered them. E.g.

def define_bindings(widget):
    widget.bind("<Button-1>", do-something-cool)

def do-something-cool(event):
    #Your code to execute on the event trigger

Now what if you had some arguments to pass? Something as simple as passing 2 arguments to store the coordinates of a mouse-click. You can easily do it like this:

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

Now you can argue that this can be done using global variables, but do you really want to bang your head worrying about memory management and leakage especially if the global variable will just be used in one particular place? That would be just poor programming style.

In short, lambdas are awesome and should never be underestimated. Python lambdas are not the same as LISP lambdas though (which are more powerful), but you can really do a lot of magical stuff with them.


回答 15

通常,Lambda与函数式编程风格密切相关。您可以通过将函数应用于某些数据并合并结果来解决问题,这是Google用于实现其大多数算法的想法。

以函数式编程风格编写的程序易于并行化,因此在现代多核计算机中变得越来越重要。简而言之,不,您不应该忘记它们。

Lambdas are deeply linked to functional programming style in general. The idea that you can solve problems by applying a function to some data, and merging the results, is what google uses to implement most of its algorithms.

Programs written in functional programming style, are easily parallelized and hence are becoming more and more important with modern multi-core machines. So in short, NO you should not forget them.


回答 16

首先恭喜您找出了lambda。在我看来,这是一个非常强大的构造。如今,趋向于函数式编程语言的趋势无疑表明,既不应该避免也不希望在不久的将来重新定义它。

您只需要稍微有所不同即可。我相信您很快就会喜欢它。但是,如果仅处理python,请小心。因为lambda不是真正的闭包,所以它以某种方式“被破坏了”:pythons lambda被破坏了

First congrats that managed to figure out lambda. In my opinion this is really powerful construct to act with. The trend these days towards functional programming languages is surely an indicator that it neither should be avoided nor it will be redefined in the near future.

You just have to think a little bit different. I’m sure soon you will love it. But be careful if you deal only with python. Because the lambda is not a real closure, it is “broken” somehow: pythons lambda is broken


回答 17

我才刚开始使用Python,然后先进入Lambda,这花了我一段时间才弄清楚。

请注意,这并不是对任何事情的谴责。每个人都有一套不同的事情,这些事情并非易事。

lambda是在现实生活中应该被遗忘的那些“有趣”语言项目之一吗?

没有。

我确定在某些情况下可能需要使用它,但是鉴于它的晦涩之处,

这不是晦涩的。我工作的过去2个团队中,每个人都一直使用此功能。

在将来的版本中重新定义它的潜力(我基于它的各种定义的假设)

除了几年前修复闭包语义外,我还没有认真的提议在Python中重新定义它。

以及降低的编码清晰度-应该避免吗?

如果使用得当,还不清楚。相反,拥有更多可用的语言构造可提高清晰度。

这让我想起了C类型的溢出(缓冲区溢出)-指向顶部变量,并重载了设置其他字段的值。

Lambda就像缓冲区溢出吗?哇。如果您认为这是“维护噩梦”,我无法想象您将如何使用lambda。

I’m just beginning Python and ran head first into Lambda- which took me a while to figure out.

Note that this isn’t a condemnation of anything. Everybody has a different set of things that don’t come easily.

Is lambda one of those ‘interesting’ language items that in real life should be forgotten?

No.

I’m sure there are some edge cases where it might be needed, but given the obscurity of it,

It’s not obscure. The past 2 teams I’ve worked on, everybody used this feature all the time.

the potential of it being redefined in future releases (my assumption based on the various definitions of it)

I’ve seen no serious proposals to redefine it in Python, beyond fixing the closure semantics a few years ago.

and the reduced coding clarity – should it be avoided?

It’s not less clear, if you’re using it right. On the contrary, having more language constructs available increases clarity.

This reminds me of overflowing (buffer overflow) of C types – pointing to the top variable and overloading to set the other field values…sort of a techie showmanship but maintenance coder nightmare..

Lambda is like buffer overflow? Wow. I can’t imagine how you’re using lambda if you think it’s a “maintenance nightmare”.


回答 18

我使用lambda来避免代码重复。它将使函数易于理解,例如:

def a_func()
  ...
  if some_conditon:
     ...
     call_some_big_func(arg1, arg2, arg3, arg4...)
  else
     ...
     call_some_big_func(arg1, arg2, arg3, arg4...)

我用临时lambda代替

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)

I use lambdas to avoid code duplication. It would make the function easily comprehensible Eg:

def a_func()
  ...
  if some_conditon:
     ...
     call_some_big_func(arg1, arg2, arg3, arg4...)
  else
     ...
     call_some_big_func(arg1, arg2, arg3, arg4...)

I replace that with a temp lambda

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)

回答 19

我今天开始阅读David Mertz的书“ Python中的文本处理”。尽管他对Lambda的描述非常简洁,但结合了附录A中的解释使第一章的示例对我来说(最终)从页面上跳了下来,突然之间我明白了它们的价值。并不是说他的解释对您有用,我仍然处于发现阶段,因此除了以下内容之外,我不会尝试添加其他答复:我是Python新手,还是OOP Lambdas新手。既然我读了Mertz,我想我会得到它们,并且我认为它们非常有用,因为我认为它们允许使用更简洁的编程方法。

他再现了Python的Zen,其中的一句话是简单胜于复杂。作为一个非OOP程序员,使用lambda读取代码(直到上周列出了理解),我曾想过- 这很简单吗?。我今天终于意识到,实际上这些功能使代码比替代方案更具可读性和可理解性,而替代方案始终是某种形式的循环。我还意识到,就像财务报表一样,Python并不是为新手用户设计的,而是为希望受过教育的用户设计的。我不敢相信这种语言有多么强大。当我终于意识到了lambda的目的和价值时,我想撕碎大约30个程序,并在适当的地方重新开始使用lambda。

I started reading David Mertz’s book today ‘Text Processing in Python.’ While he has a fairly terse description of Lambda’s the examples in the first chapter combined with the explanation in Appendix A made them jump off the page for me (finally) and all of a sudden I understood their value. That is not to say his explanation will work for you and I am still at the discovery stage so I will not attempt to add to these responses other than the following: I am new to Python I am new to OOP Lambdas were a struggle for me Now that I read Mertz, I think I get them and I see them as very useful as I think they allow a cleaner approach to programming.

He reproduces the Zen of Python, one line of which is Simple is better than complex. As a non-OOP programmer reading code with lambdas (and until last week list comprehensions) I have thought-This is simple?. I finally realized today that actually these features make the code much more readable, and understandable than the alternative-which is invariably a loop of some sort. I also realized that like financial statements-Python was not designed for the novice user, rather it is designed for the user that wants to get educated. I can’t believe how powerful this language is. When it dawned on me (finally) the purpose and value of lambdas I wanted to rip up about 30 programs and start over putting in lambdas where appropriate.


回答 20

使用lambda的一个有用案例是提高长列表理解的可读性。在此示例中,loop_dic为简洁起见,loop_dic它很短,但可以想象它很长。如果您仅使用包含的纯值i而不是该值的lambda版本,则将获得NameError

>>> lis = [{"name": "Peter"}, {"name": "Josef"}]

>>> loop_dic = lambda i: {"name": i["name"] + " Wallace" }
>>> new_lis = [loop_dic(i) for i in lis]

>>> new_lis
[{'name': 'Peter Wallace'}, {'name': 'Josef Wallace'}]

代替

>>> lis = [{"name": "Peter"}, {"name": "Josef"}]

>>> new_lis = [{"name": i["name"] + " Wallace"} for i in lis]

>>> new_lis
[{'name': 'Peter Wallace'}, {'name': 'Josef Wallace'}]

A useful case for using lambdas is to improve the readability of long list comprehensions. In this example loop_dic is short for clarity but imagine loop_dic being very long. If you would just use a plain value that includes i instead of the lambda version of that value you would get a NameError.

>>> lis = [{"name": "Peter"}, {"name": "Josef"}]

>>> loop_dic = lambda i: {"name": i["name"] + " Wallace" }
>>> new_lis = [loop_dic(i) for i in lis]

>>> new_lis
[{'name': 'Peter Wallace'}, {'name': 'Josef Wallace'}]

Instead of

>>> lis = [{"name": "Peter"}, {"name": "Josef"}]

>>> new_lis = [{"name": i["name"] + " Wallace"} for i in lis]

>>> new_lis
[{'name': 'Peter Wallace'}, {'name': 'Josef Wallace'}]

回答 21

我可以举一个例子,说明我实际上需要严重的lambda。我正在制作一个图形程序,其中使用权在文件上单击并为其分配三个选项之一。事实证明,在Tkinter(我正在编写的GUI接口程序)中,当有人按下按钮时,无法将其分配给带有参数的命令。因此,如果我选择其中一个选项并希望选择的结果是:

print 'hi there'

那没什么大不了的。但是,如果我需要选择一个特定的细节怎么办?例如,如果我选择选项A,则它调用一个函数,该函数接受依赖于选项A,B或C的某些参数,TKinter不支持此功能。实际上,Lamda是解决此问题的唯一选择。

I can give you an example where I actually needed lambda serious. I’m making a graphical program, where the use right clicks on a file and assigns it one of three options. It turns out that in Tkinter (the GUI interfacing program I’m writing this in), when someone presses a button, it can’t be assigned to a command that takes in arguments. So if I chose one of the options and wanted the result of my choice to be:

print 'hi there'

Then no big deal. But what if I need my choice to have a particular detail. For example, if I choose choice A, it calls a function that takes in some argument that is dependent on the choice A, B or C, TKinter could not support this. Lamda was the only option to get around this actually…


回答 22

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

以下是示例:

实现空对象模式:

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

I use it quite often, mainly as a null object or to partially bind parameters to a function.

Here are examples:

to implement null object pattern:

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

for parameter binding:

let say that I have the following API

def dump_hex(file, var)
    # some code
    pass

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

Then, when I wan’t to quickly dump the recieved data to a file I do that:

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

回答 23

我用 lambda用来创建包含参数的回调。与编写一种执行相同功能的方法相比,在一行中编写一个lambda更加干净。

例如:

import imported.module

def func():
    return lambda: imported.module.method("foo", "bar")

相对于:

import imported.module

def func():
    def cb():
        return imported.module.method("foo", "bar")
    return cb

I use lambda to create callbacks that include parameters. It’s cleaner writing a lambda in one line than to write a method to perform the same functionality.

For example:

import imported.module

def func():
    return lambda: imported.module.method("foo", "bar")

as opposed to:

import imported.module

def func():
    def cb():
        return imported.module.method("foo", "bar")
    return cb

回答 24

我是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)

I’m a python beginner, so to getter a clear idea of lambda I compared it with a ‘for’ loop; in terms of efficiency. Here’s the code (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)

回答 25

Lambda是一个过程构造函数。尽管Python的lambda并不是很强大,但是您可以在运行时合成程序。请注意,很少有人了解这种编程。

Lambda is a procedure constructor. You can synthesize programs at run-time, although Python’s lambda is not very powerful. Note that few people understand that kind of programming.