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

时间:2010-10-12 04:31:25

标签: python recursion lambda

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

我是Python新手并试图了解lambda表达式的工作原理。有人可以解释这种递归是如何工作的吗?我能够理解10 == 11将是'false',这就是rec_fn将被递归地再次调用的方式。

但是我无法得到的是这种看似新的编写lambda表达式的方法。

lambda x: x+y发生了什么,参数'x'进入未命名的函数?

另外,为什么

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

什么是rec_fn?它是函数还是变量?

5 个答案:

答案 0 :(得分:4)

将函数调用视为运算符可能会有所帮助。因为它就是这样。当你做rec_fn()时,你做了两件事。首先,您将获得对名为rec_fn的对象的引用。这恰好是一个函数,但这并不重要(在Python中,函数之外的对象是可调用的)。然后有()表示“调用我刚才命名的对象”。可以在不调用函数的情况下获取函数的引用,只需省略括号,然后就可以为它指定不同的名称,然后可以通过添加来调用它们。括号中。

def func1():
   print "func1"

func2 = func1

func2()       # prints "func1"

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

func3 = lambda x: x+1

您正在执行与上面func2 = func1行相同的操作,除了lambda表达式 该函数。语法不同;可以定义lambda函数而不给它起名字。

Lambdas可以有任意数量的参数,因此lambda: 3是一个不带参数且总是返回3的函数,而lambda x, y: x+y是一个带有两个参数并返回其总和的函数。

关于or的使用方式,它正在利用短路。基本上,or知道如果它的第一个操作数是True ,它不需要评估第二个,因为无论第二个参数是什么,结果都将是True。因此,您可以将其视为if not 10==11: rec_fn()。顺便说一下,and也会短路,但如果第一个参数是False,它会这样做,因为它知道结果将是False而不管第二个参数是什么。< / p>

答案 1 :(得分:0)

函数调用 - 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变量存储一个函数对象,以后可以使用()调用它。方法大致相同(可以调用的函数),但它们是属性而不是变量

答案 2 :(得分:0)

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

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

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

而你用rec_fn()调用一个没有参数的函数,因此没有x

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

这是试图将函数调用rec_fn()(右边有一个表达式)的结果设置为一个值。没有变量可以将lambda函数赋值给。

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

这里rec_fn在包含lambda的变量中(实质上就像一个函数指针)

答案 3 :(得分:0)

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

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

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

可以根据需要使用尽可能多的参数编写Lambda。在lambda: ...的情况下,没有指定,所以它是一个“不带参数的函数。”

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

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

试着记住差异。

答案 4 :(得分:0)

这可能是更容易理解的递归示例,因子lambda版本:

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

输出:

3628800

请注意Python的递归限制。

使用或作为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)