Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we have this behavior in a Python dictionary generator?

Why in the first case the dictionary keys have been overwritten, but in the second case the values have been overwritten?

>>> a = {'a': 1, 'b': {'c': 3}}
>>> {None if v.__class__ == dict else k: v for k, v in a.items()}
{'a': 1, None: {'c': 3}}
>>> {k: v if v.__class__ != dict else None for k, v in a.items()}
{'a': 1, 'b': None}
like image 587
Roman Avatar asked Sep 22 '26 02:09

Roman


1 Answers

If we rewrite as a standard loop, the situation may become clearer (note that I've used isinstance as a better class check):

Option 1:

d = {}
for k, v in a.items():
    d[None if isinstance(v, dict) else k] = v

Option 2:

d = {}
for k, v in a.items():
    d[k] = None if isinstance(v, dict) else v

Clearly the former is modifying the keys, the latter is modifying the values.


You don't say what you actually wanted to happen, but if you were trying to skip over k: v pairs where the value is a dictionary, i.e.:

d = {}
for k, v in a.items():
    if not isinstance(v, dict):
        d[k] = v

then the "dictionary comprehension" equivalent would look like:

{k: v for k, v in a.items() if not isinstance(v, dict)}

Note that the if condition appearing after the for acts as a filter.

like image 152
jonrsharpe Avatar answered Sep 24 '26 17:09

jonrsharpe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!