Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can i use dictionary comprehensions where nested dict or list may occur

How can I use dictionary comprehension for values that are literals or list

Right now I'm able to iterate through a nested dictionary and get as a result dict with nested values, but I would like to include in the output dict, list, and literals (int, str)

Here is my example ( I know that isinstance is not needed here)

nested_dict = {'first':{'a':1}, 'second':{'b':2}, 'third': 3, 'fourth': [1, 2, 3, 4]}

float_dict = {
    outer_k: { float(inner_v)
        for (inner_k, inner_v) in outer_v.items()}
            for (outer_k, outer_v) in nested_dict.items()
                if isinstance(outer_v, dict) 
}

print(float_dict)

Expected output:

{'first': {'a': 1.0}, 'second': {'b': 2.0}, 'third': 3.0, 'fourth': [1.0, 2.0, 3.0, 4.0]}
like image 254
Andrew Avatar asked Jan 20 '26 22:01

Andrew


2 Answers

It's not (reasonably) possible using a single comprehension, you want a recursive function like this:

def floatify(v):
    if isinstance(v, list):
        return list(map(floatify, v))
    if isinstance(v, dict):
        return {k: floatify(_v) for k, _v in v.items()}
    return float(v)
>>> floatify(nested_dict)
{'first': {'a': 1.0}, 'second': {'b': 2.0}, 'third': 3.0, 'fourth': [1.0, 2.0, 3.0, 4.0]}

Note that you can make this function even more generic:

def anyify(v, f):
    if isinstance(v, list):
        return [anyify(_v, f) for _v in v]
    if isinstance(v, dict):
        return {k: anyify(_v, f) for k, _v in v.items()}
    return f(v)

anyify(nested_dict, float)
like image 185
deceze Avatar answered Jan 23 '26 11:01

deceze


Or without recursion you could kinda make it in one-liner:

{outer_k: ({inner_k: float(inner_v) for (inner_k, inner_v) in outer_v.items()} if isinstance(outer_v, dict) else ([float(i) for i in outer_v] if isinstance(outer_v, list) else float(outer_v))) for (outer_k, outer_v) in nested_dict.items()}

Ex:

nested_dict = {'first':{'a':1}, 'second':{'b':2}, 'third': 3, 'fourth': [1, 2, 3, 4]}

float_dict = {outer_k: ({inner_k: float(inner_v) for (inner_k, inner_v) in outer_v.items()} if isinstance(outer_v, dict) else ([float(i) for i in outer_v] if isinstance(outer_v, list) else float(outer_v))) for (outer_k, outer_v) in nested_dict.items()}
print(float_dict)

Output:

{'first': {'a': 1.0}, 'second': {'b': 2.0}, 'third': 3.0, 'fourth': [1.0, 2.0, 3.0, 4.0]}
like image 20
U12-Forward Avatar answered Jan 23 '26 11:01

U12-Forward