lambda 是如何工作的?
我正在使用 python 官方网站上的教程学习 python,并遇到了 这个示例< /a>:
>>> def make_incrementor(n):
... return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43
x
从哪里获取它的值?我不熟悉 lambda 的工作原理,我从 javascript 中可以很好地理解匿名函数,但这让我感到困惑。有人愿意透露一些信息吗?我将不胜感激。
I'm learning python using the tutorial on the official python website and came across this example:
>>> def make_incrementor(n):
... return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43
Where does x
get it's value from? I'm not familiar with how lambda works, I understand anonymous functions just fine from javascript but this has me stumped. Anyone care to shed some light? I'd be grateful.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
考虑一下这一点。
f
是由make_incrementor
函数创建的对象。它是一个 lambda,一个“匿名函数”。
当我们将
f
应用于某个值时,x
的值就会显示出来。Consider this.
f
is the object created by themake_incrementor
function.It is a lambda, an "anonymous function".
The value for
x
showed up when we appliedf
to a value.首先,这是 JavaScript 的翻译:
lambda 表达式由三部分组成。
lambda
(在 JavaScript 中,单词function
)(...)
中的部分){...}
中的部分)参数列表是冒号之前的部分。这些参数在表达式的范围内可见。无论表达式的计算结果是什么,都会作为函数的结果返回。
与 JavaScript 不同,lambda 只能包含单个表达式;你不能用 lambda 创建匿名多行函数。
First off, here's a translation into JavaScript:
A lambda expression consists of three parts.
lambda
(In JavaScript, the wordfunction
)(...)
){...}
, automatically returned)The list of parameters is the part before the colon. These parameters are visible within the scope of the expression. Whatever the expression evaluates to is returned as the result of the function.
Unlike in JavaScript, a lambda can only contain a single expression; you can't make an anonymous multi-line function with lambda.
免责声明:我几乎没有 Python 背景。这超出了我的Scheme/lambda 演算知识。
make_incrementor 定义一个函数来制作函数。 make_incrementor(42) 返回一个函数,其中 x 绑定到 lambda,n 的值为 42。当您调用函数 f 时,f 的参数将替换绑定变量。
Disclaimer: I have pretty much no Python background. This is going off my Scheme/lambda calculus knowledge.
make_incrementor defines a function to make functions. make_incrementor(42) returns a function with x bounded to the lambda, and n with a value of 42. When you call the function f, the argument of f replaces the bound variable.
lambda
为 Python 带来了一些 lambda 演算。本质上,这就是正在发生的事情:通常在 lambda 演算中,语句看起来像这样:这会将
3
和4
传递给add
函数并将结果存储在sum
中。不过,我们也可以按照add 3
的方式编写一些内容。现在,由于add
需要两个参数,因此我们现在得到一个需要一个参数的对象(或函数,如果你愿意的话)。然后,该函数将调用add
,并将 3 作为其第一个参数,并将我们传递的任何内容作为第二个参数。我们现在可以这样做:这与前面的示例等效。不过,现在只要您想将 3 加到某项上,您就可以使用
func
。 (当然,这在本例中似乎没有用,但在更复杂的情况下却很有用)。所有这些都与柯里化密切相关,这是大多数函数式语言。如果您对 lambda 演算及其与常规数学的相似性感兴趣,我强烈建议您查看 哈斯克尔。
lambda
brings some lambda calculus to Python. In essence, this is what's happening: normally in lambda calculus a statement would look something like this:This would pass
3
and4
to theadd
function and store the result insum
. However, we could also write something along the lines ofadd 3
. Now, sinceadd
expects two arguments, we now get an object (or function, if you will) expecting one argument. That function will then calladd
with 3 as its first argument and whatever we pass it as the second argument. We can now do this:This will be equivalent to the previous example. However, you can now use
func
whenever you want to add 3 to something. (Granted, this doesn't seem useful in this example, but in more complex situations it is).All this is closely related to currying, something very central in most functional languages. If you're interested in lambda calculus and its similarity to regular mathematics, I highly recommend that you take a look at Haskell.
当调用 make_incrementor() 时,它会创建并返回一个 lambda 函数。在此过程中,参数
n
的值被存储或记住在创建的函数对象中。如果您使用不同的n
再次调用它,则会返回不同的函数。When
make_incrementor()
is called it creates and returns alambda
function at that time. In the process the value of the argumentn
gets stored or remembered in the function object created. If you called it again with a differentn
a different function would be returned.x
从用于调用f
的参数中获取其值。n
从用于调用make_incrementor
的参数中获取其值。x
gets its value from the parameter used to callf
.n
gets its value from the parameter used to callmake_incrementor
.make_incrementor 是一个返回函数的函数:
当我们调用 make_incrementor 时,我们将参数 42 绑定到 n,并返回具体函数:
因此,我们将返回的这个函数看起来像:
f 绑定到返回的函数,因此 f 在概念上将看起来像:
当我们调用 f 时,我们提供 x 的值
make_incrementor is a function that returns a function:
When we call make_incrementor, we bind the parameter 42 to n, and return the concrete function:
This function we will return will therefore look like:
f is bound to the returned function, so f will conceptually look like:
When we call f, we provide the value for x
我是这样理解 lambda 的:
当我们写 x2 时,我们经常混淆两个不同的想法。考虑:
x2 有奇数个因子。
x2 大于 x。
x2 有导数 2x。
x2 有一个逆函数,即 sqrt(x)。
前两个陈述是关于特定但未指定的数字的平方。在这些陈述中,“x”代表任意单个事物,x2 代表单个相关事物。
第三和第四条语句是关于函数 x2 的。但除了上下文和对微积分的共同理解之外,这在 3. 和 4. 中并没有明确传达。我们需要一个符号设备来区分 x2 单个(但任意)值和 x2 函数。设备还需要表明它是 x 的函数。因此 lambda 被发明了:
“lambda xx2”被写入来进行这种区分并传达“x 的函数,其在 x 处的值为 x2”。 lambda 运算符采用名称 (x) 和表达式 (x2) 并返回一个函数。这与正常函数定义具有相同的结果,只是函数不会自动接收名称。
Here's how I understand lambda:
When we write x2, we often confuse two distinct ideas. Consider:
x2 has an odd number of factors when x is an integer.
x2 is larger than x when x>1.
x2 has derivative 2x.
x2 has an inverse, namely sqrt(x), for x>0.
The first two statements are about the square of a particular but unspecified number. In those statements "x" represents an arbitrary single thing, and x2 represents a single related thing.
The third and fourth statement are about x2, the function. But this is not clearly communicated in 3. and 4. except by context and shared understanding of Calculus. We need a notational device to distinguish between x2 the single (but arbitrary) value, and x2 the function. The device also needs to communicate that it is a function of x. Therefore lambda is invented:
"lambda x.x2" is written to make this distinction and communicate "the function of x whose value at x is x2". The lambda operator takes a name (x) and an expression (x2) and returns a function. This has the same consequences as normal function definition, except that the function doesn't automatically receive a name.