【问题标题】:Lambda with different expression returns same output [duplicate]具有不同表达式的 Lambda 返回相同的输出
【发布时间】:2021-05-08 09:55:40
【问题描述】:

以这段代码sn-p为例:

a = []
for x in range(2):
    a.append(lambda: print(x))
print(a[0](), a[1]())

输出是:

1 1

但我预计会是这样

0 1

我该如何解决这个问题?

【问题讨论】:

  • 尝试将del x 放在for loop 和最后一个print statement 之间。当您执行 lambda 时,它正在寻找变量 x,它的最新值为 1。

标签: python python-3.x


【解决方案1】:

使用默认参数:

a = []
for x in range(2):
    a.append(lambda x = x: print(x))
print(a[0](), a[1]())

这是可行的,因为在创建函数时会评估默认值。否则所有 lambda 函数都将指向 x 的最后一个值,即 1。

【讨论】:

  • 你能解释一下为什么会这样吗?这将是有用的。 Abdul 添加了解释为什么 OP 的代码不起作用,但我认为这对解释这一点很有用。
  • @Rahul 发布了解释。另请参阅 Abdul Niyas P M 的回答。
  • 它基本上是创建一个参数 x 并为其分配一个默认值,因此等价于 >>>lambda x = x: print(x) 是 >>>def someThing(x=x):打印(x)
  • 谢谢@sarartur。我猜 Avi Shah 已经知道答案了。感谢分享。
【解决方案2】:

@sarartur 已经提供了解决方案。以下是对这种行为的更多解释。

这称为Late Binding Closures。引用自博客,

Python 的闭包是后期绑定的。这意味着在调用内部函数时会查找闭包中使用的变量的值。

因此,每当调用任何返回的函数时,都会在调用时在周围范围内查找 i 的值。到那时,循环已经完成,i 的最终值为 1。

【讨论】:

    【解决方案3】:

    发生这种情况是因为您的lambda 表达式正在打印x,但x 正在由您的for 循环更新,所以当您的lambda 表达式被调用时,x 已完成1 的值,因为这是 range(2) 中的最后一个值。

    >>> for num in range(10):
    ...     pass
    ...
    >>> num
    9
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-08
      • 2016-01-09
      相关资源
      最近更新 更多