这个 Python Lambda 递归表达式是如何工作的?

发布于 2024-09-27 05:23:00 字数 427 浏览 2 评论 0原文

rec_fn = lambda: 10==11 or rec_fn()
rec_fn()

我是 Python 新手,正在尝试了解 lambda 表达式的工作原理。有人可以解释一下这个递归是如何工作的吗?我能够理解 10==11 将是“假”,这就是 rec_fn 将被一次又一次递归调用的方式。

但我无法理解这种看似新的编写 lambda 表达式的方法。

lambda x: x+y 发生了什么,其中有一个参数“x”进入未命名函数?

另外,为什么是

rec_fn() = lambda: .... // a syntax error
rec_fn = lambda: .... //syntactically correct - WHY?

rec_fn?它是函数还是变量?

rec_fn = lambda: 10==11 or rec_fn()
rec_fn()

I am new to Python and trying to understand how lambda expressions work. Can somebody explain how this recursion is working? I am able to understand that 10==11 will be 'false' and that's how rec_fn will be called again and again recursively.

But what I am not able to get is this seemingly new way of writing a lambda expression.

whatever happened to lambda x: x+y where there is a parameter 'x' going into the unnamed function?

Also, why is

rec_fn() = lambda: .... // a syntax error
rec_fn = lambda: .... //syntactically correct - WHY?

What is rec_fn? Is it a function or a variable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

鼻尖触碰 2024-10-04 05:23:00

将函数调用视为运算符可能会有所帮助。因为这就是它的本质。当你执行rec_fn()时,你正在做两件事。首先,您将获得对名为 rec_fn 的对象的引用。这恰好是一个函数,但这并不重要(在Python中,除了函数之外的对象都是可调用的)。然后是(),意思是“调用我刚刚命名的对象”。可以在不调用函数的情况下获取对函数的引用,只需去掉括号即可,然后您可以为其分配不同的名称,然后可以通过添加以下名称来使用其中任何名称来调用它:括号。

def func1():
   print "func1"

func2 = func1

func2()       # prints "func1"

现在您可以看到 lambda 是如何工作的。

func3 = lambda x: x+1

您所做的操作与上面的 func2 = func1 行相同,只是 lambda 表达式是函数。只是语法不同而已;无需命名即可定义 lambda 函数。

Lambda 可以有任意数量的参数,因此 lambda: 3 是一个不带参数且始终返回 3 的函数,而 lambda x, y: x+y 是一个函数它接受两个参数并返回它们的总和。

至于or的使用方式,它利用了短路。基本上,or知道它的第一个操作数是否是True,它不需要计算第二个参数,因为无论第二个参数是什么,结果都将为True。因此,您可以将其读作 if not 10==11: rec_fn()。顺便说一句,也会短路,尽管如果第一个参数是False,它就会短路,因为它知道结果将为False不管第二个参数是什么。

It may help to think of a function call as an operator. Because that's what it is. When you do rec_fn() you are doing two things. First, you're getting a reference to the object named rec_fn. This happens to be a function, but that doesn't matter (in Python, objects besides functions are callable). Then there is () which means "call the object I just named." It is possible to get a reference to a function without calling it, just by leaving off the parentheses, and then you can assign it different names, any of which can then be used to call it by adding the parentheses.

def func1():
   print "func1"

func2 = func1

func2()       # prints "func1"

Now you can see how the lambda works.

func3 = lambda x: x+1

You are doing the same as the func2 = func1 line above, except the lambda expression is the function. The syntax is just different; the lambda function can be defined without giving it a name.

Lambdas can have any number of parameters, so lambda: 3 is a function that takes no parameters and always returns 3, while lambda x, y: x+y is a function that takes two parameters and returns their sum.

As to the way or is being used, it's taking advantage of short-circuiting. Basically, or knows that if its first operand is True, it doesn't need to evaluate the second, because the result is going to be True regardless of what the second argument is. You could thus read this as if not 10==11: rec_fn(). By the way, and also short-circuits, although it does so if the first argument is False since it knows that the result will be False regardless of what the second argument is.

明媚殇 2024-10-04 05:23:00
  rec_fn = lambda: 10==11 or rec_fn()
  rec_fn()

与此表达式类似,但是此表达式需要一个参数,

rec_fn = lambda x: 10==11 or rec_fn(x)
x = ...
rec_fn(x)

而您正在调用一个没有参数的函数,因此没有 x 这是rec_fn(),

rec_fn() = lambda: .... // a syntax error

这是尝试设置函数调用rec_fn()的结果(右有侧面表达)到一个值。那里没有变量可以分配 lambda 函数。

rec_fn = lambda: .... //syntactically correct - WHY?

这里的rec_fn是保存lambda的变量(本质上就像一个函数指针)

  rec_fn = lambda: 10==11 or rec_fn()
  rec_fn()

is the similar to this expression, however this one requires a parameter,

rec_fn = lambda x: 10==11 or rec_fn(x)
x = ...
rec_fn(x)

whereas you'r rec_fn() with you're calling a function with no parameters hence no x

rec_fn() = lambda: .... // a syntax error

This is trying to set result of the function call rec_fn() (a right had side expression) to a value. There is no variabele there to assign the lambda function to.

rec_fn = lambda: .... //syntactically correct - WHY?

here rec_fn in the variable that holds the lambda (in essence like a function pointer)

微暖i 2024-10-04 05:23:00

函数调用 - x() - 是一个表达式。这是赋值左侧的合法语法结构。应该发生什么? (这与 42 = lambda: .... 大致相同)

在第二种情况下,您只需分配创建的新函数对象(使用 lambda 关键字) 到变量(名为 rec_fn)并且不调用函数。

也许更清晰的方法是使用(首选)非 lambda 嵌套函数方法:

# just for example, not really useful as it is unless you like to eat CPU
def rec_fn():
  return 10 == 11 or rec_fn()

rec_fn()

lambda 关键字只是一个语法快捷方式,可以用作表达式的一部分。

在上述情况下,rec_fn 是一个局部变量(假设所述代码嵌套在函数/方法中)。 rec_fn 变量存储一个函数对象,稍后可以使用 () 调用该函数对象。方法大致相同(可以调用的函数),但它们是属性而不是变量。

A function invocation -- x() -- is an expression. It is lot a legal syntax construct on the left side of an assignment. What should happen? (It is roughly the same as saying 42 = lambda: ....)

In the 2nd case, you are simply assigning the new function object created (with the lambda keyword) to a variable (named rec_fn) and not invoking a function.

Perhaps a more clear way is to use the (preferred) non-lambda nested function approach:

# just for example, not really useful as it is unless you like to eat CPU
def rec_fn():
  return 10 == 11 or rec_fn()

rec_fn()

The lambda keyword is just a syntactic shortcut which can be used as part of an expression.

rec_fn is a local variable in the above cases (assuming said code is nested in a function/method). The rec_fn variable stores a function object which can later be invoked with (). Methods are roughly the same (functions which can be invoked), but they are properties and not variables.

久而酒知 2024-10-04 05:23:00
rec_fn = lambda: 10==11 or rec_fn()
rec_fn()

函数体在执行之前不会被求值。一开始,rec_fn没有值。 lambda 的内容只是一些对某个变量 rec_fn 进行函数调用的表达式。它还不会失败,因为该函数尚未执行。然后将新的 lambda 函数分配给变量 rec_fn,然后调用该函数。现在,由于该函数正在执行,因此它将执行直到函数调用为止的动作。表达式为10==11或rec_fn()。它是一个 or 表达式,因此计算左侧。 10==11 为 False,因此它必须评估右侧,即对某个函数(或其他可调用对象)rec_fn 的函数调用。此时,rec_fn 被分配给我们刚刚创建的函数(本身),因此它被调用(递归)。等等。它相当于:

def rec_fn():
    return 10==11 or rec_fn()

可以根据需要使用任意多个参数来编写 Lambda。对于 lambda: ... ,没有指定任何内容,因此它是一个“不带参数的函数”。

请记住,函数(以及扩展的 lambda)是第一类对象。您可以像任何其他对象一样传递它们并将它们存储到其他变量中。

rec_fn = lambda: ...

没问题,因为您已经定义了一个 lambda 函数并将其存储到变量 rec_fn 中。可以像调用任何其他函数一样使用该名称 rec_fn() 来调用它。

rec_fn() = lambda: ...

另一方面会失败,因为您无法将任何内容分配给函数调用 rec_fn() 的结果。

以这种方式定义函数与普通函数定义有很大不同:

def rec_fn2(): # here you may use the parens with the name to indicate it takes no arguments
    ...        # unlike in the lambda assignment above

只需尝试记住差异即可。

rec_fn = lambda: 10==11 or rec_fn()
rec_fn()

The body of a function is not evaluated until it is executed. At the start, rec_fn has no value. The contents of the lambda is just some expression that has some function call on some variable rec_fn. It won't fail yet because the function isn't executed yet. The new lambda function is then assigned to the variable rec_fn followed by a call to the function. Now since the function is being executed, it will go through the motions up to the function call. The expression is 10==11 or rec_fn(). It's an or expresison so the left hand side is evaluated. 10==11 is False so it must evaluate the right hand side which is a function call to some function (or other callable object) rec_fn. At that point, rec_fn is assigned to the function we just created (itself) so it gets called (recursively). And so on. It is equivalent to:

def rec_fn():
    return 10==11 or rec_fn()

Lambdas can be written using as many parameters as necessary. In the case of lambda: ..., there are none specified so it's a "function that takes no arguments."

Just remember, functions (and by extension, lambdas) are first class objects. You can pass them around like any other object and store them into other variables.

rec_fn = lambda: ...

is fine because you've defined a lambda function and stored it into the variable rec_fn. It can be called by using that name rec_fn() like you would any other function.

rec_fn() = lambda: ...

on the other hand fails because you cannot assign anything to the result of the function call rec_fn().

Defining a function this way is much different than a normal function definition:

def rec_fn2(): # here you may use the parens with the name to indicate it takes no arguments
    ...        # unlike in the lambda assignment above

Just try to remember the difference.

聆听风音 2024-10-04 05:23:00

这可能是更容易理解的递归、阶乘 lambda 版本的示例:

fact = lambda x: 1 if x == 0 else x*fact(x-1)
prin(fact(10))

输出:

3628800

不过,请注意 Python 的递归限制。

使用 or 作为 if..else 的示例:

print 1 or 'a'
print 'a' or False
print False or True or 0/9
fact_or = lambda x: x == 0 and 1 or x * fact_or(x-1)
print fact_or(10)

This is maybe more understandable example of recursion, factorial lambda version:

fact = lambda x: 1 if x == 0 else x*fact(x-1)
prin(fact(10))

Output:

3628800

Be aware of Python's recursion limit, though.

Example of using or as this if..else:

print 1 or 'a'
print 'a' or False
print False or True or 0/9
fact_or = lambda x: x == 0 and 1 or x * fact_or(x-1)
print fact_or(10)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文