python - 列表理解和 for 循环中的 Lambda

标签 python lambda functional-programming list-comprehension

<分区>

我想要一个 lambda 列表,作为一些繁重计算的缓存,我注意到了这一点:

>>> [j() for j in [lambda:i for i in range(10)]]
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]

虽然

>>> list([lambda:i for i in range(10)])
[<function <lambda> at 0xb6f9d1ec>, <function <lambda> at 0xb6f9d22c>, <function <lambda> at 0xb6f9d26c>, <function <lambda> at 0xb6f9d2ac>, <function <lambda> at 0xb6f9d2ec>, <function <lambda> at 0xb6f9d32c>, <function <lambda> at 0xb6f9d36c>, <function <lambda> at 0xb6f9d3ac>, <function <lambda> at 0xb6f9d3ec>, <function <lambda> at 0xb6f9d42c>]

这意味着 lambda 是独特的函数,但它们不知何故都共享相同的索引值。

这是错误还是功能?我该如何避免这个问题?它不仅限于列表理解......

>>> funcs = []
... for i in range(10):
...     funcs.append(lambda:i)
... [j() for j in funcs]
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]

最佳答案

lambda 在您调用它时返回 i 的值。由于您在循环运行结束后调用 lambda,因此 i 的值将始终为 9。

您可以在 lambda 中创建一个本地 i 变量来保存定义 lambda 时的值:

>>> [j() for j in [lambda i=i:i for i in range(10)]]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

另一个解决方案是创建一个返回 lambda 的函数:

def create_lambda(i):
    return lambda:i
>>> [j() for j in [create_lambda(i) for i in range(10)]]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

这是有效的,因为每次调用 create_lambda 都会创建一个不同的闭包(保存不同的 i 值)。

关于python - 列表理解和 for 循环中的 Lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10070477/

相关文章:

python - 全局名称 <function> 未定义错误 Python

python - 如何为同一组中的每个值分配一个序列号? Python

python - xml 从 python 字典中转义

java - Lambda 表达式在 Java 8 中不起作用?

haskell - 单子(monad)可以被视为计算(或计算过程)的具体化吗?

Python 在 MySQL 数据库中插入值 <= 1e-7

python - 如何通过继承在python中对请求进行子类化

java - 使用 Java 8 流如何将 Map<String, List<Something>> 转换为 Map<String, Integer>?

flutter - 事件的返回函数

functional-programming - 如何在 OCaml 中使用 Map/定义实际上是 Map 的类型?