gpt4 book ai didi

python - 在 Python 中,为什么 lambda 表达式可以引用正在定义的变量而不是列表?

转载 作者:IT老高 更新时间:2023-10-28 22:08:22 27 4
gpt4 key购买 nike

这更像是一种好奇心,但我刚刚注意到以下内容。如果我要定义一个自引用的 lambda,我可以很容易地做到这一点:

>>> f = lambda: f
>>> f() is f
True

但如果我要定义一个自引用列表,我必须在不止一个语句中这样做:

>>> a = [a]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> a = []
>>> a.append(a)
>>> a[0] is a
True
>>> a
[[...]]

我还注意到,这不仅限于列表,而且似乎除了 lambda 之外的任何其他表达式都无法引用赋值左侧的变量。例如,如果你有一个只有一个节点的循环链表,你就不能简单地去:

>>> class Node(object):
... def __init__(self, next_node):
... self.next = next_node
...
>>> n = Node(n)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'n' is not defined

相反,您必须在两个语句中做到这一点:

>>> n = Node(None)
>>> n.next = n
>>> n is n.next
True

有谁知道这种差异背后的哲学是什么?我知道递归 lambda 的使用频率更高,因此支持自引用对 lambda 很重要,但为什么不允许它进行任何赋值呢?

编辑:下面的答案很好地阐明了这一点。原因是 Python 中的 lambdas 中的变量在每次调用 lambda 时都会计算,而不是在定义时计算。从这个意义上说,它们与使用 def 定义的函数完全一样。我编写了以下代码来试验它是如何工作的,包括 lambdas 和 def 函数,以防它可能有助于任何人澄清它。

>>> f = lambda: f
>>> f() is f
True
>>> g = f
>>> f = "something else"
>>> g()
'something else'
>>> f = "hello"
>>> g()
'hello'
>>> f = g
>>> g() is f
True

>>> def f():
... print(f)
...
>>> f()
<function f at 0x10d125560>
>>> g = f
>>> g()
<function f at 0x10d125560>
>>> f = "test"
>>> g()
test
>>> f = "something else"
>>> g()
something else

最佳答案

lambda 中的表达式在函数被调用 时计算,而不是在定义时计算。

换句话说,在你调用它之前,Python 不会评估你的 lambda 中的 f。而且,到那时, f 已经在当前范围内定义(它是 lambda 本身)。因此,不会引发 NameError


请注意,这样的行不是这种情况:

a = [a]  

当 Python 解释这种类型的行(称为赋值语句)时,它会立即计算 = 右侧的表达式。此外,对于在当前范围内未定义的右侧使用的任何名称,都会引发 NameError

关于python - 在 Python 中,为什么 lambda 表达式可以引用正在定义的变量而不是列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22335171/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com