Need help on why this code snippet does not return as I'd expect
>>> a = 1
>>> v = ["a", "b", "c"]
>>> {e for e in v if locals().get(e) is None}
set(['a', 'c', 'b'])
I expected it to return set(['c', 'b'])
, just like if I build a list
>>> [e for e in v if locals().get(e) is None]
['b', 'c']
In Python 2, set and dictionary comprehensions have their own scope; locals()
inside such a construct refers to that new nested scope.
List comprehensions do not, because they were implemented earlier in the language lifecycle before the developers realised that a new scope would be a much better idea. In Python 3, list comprehensions have their own scope too.
You can work around this by creating a single reference to the dictionary that locals()
returns before running your set comprehension:
>>> l = locals()
>>> {e for e in v if l.get(e) is None}
{'c', 'b'}