1

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?

Atonal
  • 520
  • 4
  • 14

0 Answers0