Have a dictionary:
data = {'Common': {'height': 165, 'weight': 70, 'measure': ['cm', 'kg']},
'Man': 'handsome',
'Woman': {'feature': 'pretty', 'weight': 50},
'Dog': {'feature': 'barks', 'height': 10, 'weight': 20}}
Would like to convert only dictionary keys to UPPERCASE.
Tried the following code:
d = {}
d1 = {}
for k, v in data.items():
if isinstance(v, dict):
for i, j in v.items():
d1[i.upper()] = j
d[k.upper()] = d1
else:
d[k.upper()] = v
print(d)
...which produces the output with unnecessary keys and height and weight rationalization as follows:
{'COMMON': {'HEIGHT': 10, 'WEIGHT': 20, 'MEASURE': ['cm', 'kg'], 'FEATURE': 'barks'},
'MAN': 'handsome',
'WOMAN': {'HEIGHT': 10, 'WEIGHT': 20, 'MEASURE': ['cm', 'kg'], 'FEATURE': 'barks'},
'DOG': {'HEIGHT': 10, 'WEIGHT': 20, 'MEASURE': ['cm', 'kg'], 'FEATURE': 'barks'}}
My expected output is:
{'COMMON': {'HEIGHT': 165, 'WEIGHT': 70, 'MEASURE': ['cm', 'kg']},
'MAN': 'handsome',
'WOMAN': {'FEATURE': 'pretty', 'WEIGHT': 50},
'DOG': {'FEATURE': 'barks', 'HEIGHT': 10, 'WEIGHT': 20}}
{{i.upper(): j} if isinstance(j, dict) else {k.upper(): v} for k, v in data.items() for i, j in v.items()}
?The issue with your code is that you are reassigning d1
if the value is a dictionary. You can solve this by using copy.deepcopy()
:
Code:
from copy import deepcopy
d = {}
d1 = {}
for k, v in data.items():
if isinstance(v, dict):
for i, j in v.items():
d1[i.upper()] = j
d[k.upper()] = deepcopy(d1)
else:
d[k.upper()] = v
Output:
>>> d
{'COMMON': {'HEIGHT': 165, 'WEIGHT': 70, 'MEASURE': ['cm', 'kg']},
'MAN': 'handsome',
'WOMAN': {'FEATURE': 'pretty', 'WEIGHT': 50},
'DOG': {'FEATURE': 'barks', 'HEIGHT': 10, 'WEIGHT': 20}}
Alternatively, as a dictionary comprehension:
>>> {k.upper(): {i.upper(): j for i, j in v.items()} if isinstance(v, dict) else v for k, v in data.items()}
{'COMMON': {'HEIGHT': 165, 'WEIGHT': 70, 'MEASURE': ['cm', 'kg']},
'MAN': 'handsome',
'WOMAN': {'FEATURE': 'pretty', 'WEIGHT': 50},
'DOG': {'FEATURE': 'barks', 'HEIGHT': 10, 'WEIGHT': 20}}