相关疑难解决方法(0)

(lambda)函数闭包捕获了什么?

最近我开始玩Python,我遇到了一些特殊的闭包方式.请考虑以下代码:

adders=[0,1,2,3]

for i in [0,1,2,3]:
   adders[i]=lambda a: i+a

print adders[1](3)
Run Code Online (Sandbox Code Playgroud)

它构建了一个简单的函数数组,它接受单个输入并返回由数字添加的输入.函数在for循环中构造,迭代器i从中循环0到3.对于这些数字中的每一个,lambda都会创建一个函数i,该函数捕获并将其添加到函数的输入中.最后一行将第二个lambda函数3作为参数调用.令我惊讶的是输出结果是6.

我期待一个4.我的理由是:在Python中,一切都是一个对象,因此每个变量都是指向它的指针.在创建lambda闭包时i,我希望它存储一个指向当前指向的整数对象的指针i.这意味着当i分配一个新的整数对象时,它不应该影响先前创建的闭包.遗憾的是,adders在调试器中检查数组表明它确实存在.所有的lambda功能指的最后一个值i,3,这将导致adders[1](3)返回6.

这让我想知道以下内容:

  • 闭包捕获的内容是什么?
  • 什么是最优雅的方式来说服lambda函数以更改其值i时不会受到影响的方式捕获当前i值?

python lambda closures

237
推荐指数
5
解决办法
4万
查看次数

在 for 循环内将映射函数附加到 PySpark RDD

有人可以帮我理解在 python for 循环中将映射函数附加到 RDD 的行为吗?

对于以下代码:

rdd = spark.sparkContext.parallelize([[1], [2], [3]])

def appender(l, i):
    return l + [i]

for i in range(3):
    rdd = rdd.map(lambda x: appender(x, i))

rdd.collect()
Run Code Online (Sandbox Code Playgroud)

我得到输出:

[[1, 2, 2, 2], [2, 2, 2, 2], [3, 2, 2, 2]]
Run Code Online (Sandbox Code Playgroud)

而使用以下代码:

rdd = spark.sparkContext.parallelize([[1], [2], [3]])

def appender(l, i):
    return l + [i]

rdd = rdd.map(lambda x: appender(x, 1))
rdd = rdd.map(lambda x: appender(x, 2))
rdd = rdd.map(lambda x: appender(x, 3))

rdd.collect()
Run Code Online (Sandbox Code Playgroud)

我得到预期的输出:

[[1, 1, 2, 3], …
Run Code Online (Sandbox Code Playgroud)

apache-spark pyspark

5
推荐指数
1
解决办法
4711
查看次数

lambda 为全局变量赋值?

我正在使用 tkinter 并尝试在按下按钮时为全局变量赋值。这是代码: popup.add_command(label="Allow Moving Item", command=lambda: allowMoving=True) 我收到无效的语法。你能告诉我如何解决这个问题吗?非常感谢!

python lambda assign

3
推荐指数
2
解决办法
8292
查看次数

标签 统计

lambda ×2

python ×2

apache-spark ×1

assign ×1

closures ×1

pyspark ×1