Consider the code below:
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"
My initial assumption was that a dictionary comprehension should be considered as something that's not practically any different from a syntactic abstraction.
I'm now confused: Why d["a"]()
does not print "alice"?
My expectation is that keyword: lambda: print(name)
should create a new lambda function after each iteration of the inner list, and it apparently does:
>>> print(d)
{'a': <function <dictcomp>.<lambda> at 0x7f33d5cb4158>, 'b': <function <dictcomp>.<lambda> at 0x7f33d5cb4048>, 'c': <function <lambda> at 0x7f33d4bfad08>}
The addresses of the lambda functions created for 'a'
and 'b'
are different (it's also the case that id(d['a']) != id(d['b'])
and id
guarantees uniqueness of an object).
I get that internally dict comprehension
is list an application of dict
on a list comprehension which itself is based on generator expressions, and that could hint as to why both d["a"]()
and d["b"]()
print "bob"
which is the last one on the list but not "alice"
, but then shouldn't a generator essentially not create new objects?