请考虑以下代码:
d = {
**{
keyword: lambda: print(name)
for (keyword, name) in [
("a", "alice"),
("b", "bob"),
]
},
"c": lambda: print("carol")
}
>>> d["c"]()
"carol"
>>> d["a"]()
"bob"
>>> d["b"]()
"bob"
我最初的假设是字典理解应该被视为与句法抽象实际上没有任何不同的东西。
我现在感到困惑:为什么d["a"]()
不打印“alice”?
我的期望是keyword: lambda: print(name)
应该在内部列表的每次迭代之后创建一个新的lambda函数,它显然会这样做:
>>> print(d)
{'a': <function <dictcomp>.<lambda> at 0x7f33d5cb4158>, 'b': <function <dictcomp>.<lambda> at 0x7f33d5cb4048>, 'c': <function <lambda> at 0x7f33d4bfad08>}
为'a'
和'b'
创建的lambda函数的地址是不同的(id(d['a']) != id(d['b'])
和id
也保证了对象的唯一性)。
我在内部dict comprehension
列出了一个dict
的应用程序列表解析,它本身基于生成器表达式,这可能暗示为什么d["a"]()
和{{ 1}} print d["b"]()
这是列表中的最后一个但不是"bob"
,但是生成器本身不应该创建新对象吗?