I have a nested dictionary with a list inside of it such as
{'Ka': {'Ka': ['0.80', '0.1'],
'Ba': ['0.50', '1.1'],
'FC': ['0.78', '0.0'],
'AA': ['0.66', '8.1']},
'AL': {'AR': ['2.71', '7.3'], 'KK': ['10.00', '90.0']}}
and I would like to flatten this into a dictionary as
{'Ka': {'Ka.0':'0.80', 'Ka.1':'0.1',
'Ba.0':'0.50','Ba.1': '1.1',
'FC.0':'0.78', 'FC.1':'0.0',
'AA.0':'0.66', 'AA.1':'8.1'},
'AL': {'AR.0':'2.71','AR.1':'7.3', 'KK.0':'10.00','KK.1':'90.0'}}
I tried to flatten this nested dictionary using:
import collections
def flatten(dictionary, parent_key=False, separator='.'):
"""
Turn a nested dictionary into a flattened dictionary
:param dictionary: The dictionary to flatten
:param parent_key: The string to prepend to dictionary's keys
:param separator: The string used to separate flattened keys
:return: A flattened dictionary
"""
items = []
for key, value in dictionary.items():
new_key = str(parent_key) separator key if parent_key else key
if isinstance(value, collections.MutableMapping):
items.extend(flatten(value, new_key, separator).items())
elif isinstance(value, list):
for k, v in enumerate(value):
items.extend(flatten({str(k): v}, new_key).items())
else:
items.append((new_key, value))
return dict(items)
and getting
{'Ka.Ka.0': '0.80',
'Ka.Ka.1': '0.1',
'Ka.Ba.0': '0.50',
'Ka.Ba.1': '1.1',
'Ka.FC.0': '0.78',
'Ka.FC.1': '0.0',
'Ka.AA.0': '0.66',
'Ka.AA.1': '8.1',
'AL.AR.0': '2.71',
'AL.AR.1': '7.3',
'AL.KK.0': '10.00',
'AL.KK.1': '90.0'}
but this is not what I want. I want to get something looks like the first one above. Thanks in advance.
CodePudding user response:
# use a nested dict comprehension
# use enumerate for the index of the list items and add it to the key using f-string
{key: {f"{k}.{i}": e for k, v in val.items() for i, e in enumerate(v)} for key, val in my_dict.items()}
{'Ka': {'Ka.0': '0.80', 'Ka.1': '0.1',
'Ba.0': '0.50', 'Ba.1': '1.1',
'FC.0': '0.78', 'FC.1': '0.0',
'AA.0': '0.66', 'AA.1': '8.1'},
'AL': {'AR.0': '2.71', 'AR.1': '7.3',
'KK.0': '10.00', 'KK.1': '90.0'}}
CodePudding user response:
sample_dict = {'Ka': {'Ka': ['0.80', '0.1'],
'Ba': ['0.50', '1.1'],
'FC': ['0.78', '0.0'],
'AA': ['0.66', '8.1']},
'AL': {'AR': ['2.71', '7.3'], 'KK': ['10.00', '90.0']}}
for item, value in sample_dict.items():
print(item, value, type(value))
if type(value)==dict:
for item2 in list(value):
if type(value[item2])==list:
value[item2 ".0"] = value[item2][0]
value[item2 ".1"] = value[item2][1]
del value[item2]
print(sample_dict)
and the result is:
{'Ka': {'Ka.0': '0.80', 'Ka.1': '0.1',
'Ba.0': '0.50', 'Ba.1': '1.1',
'FC.0': '0.78', 'FC.1': '0.0',
'AA.0': '0.66', 'AA.1': '8.1'},
'AL': {'AR.0': '2.71', 'AR.1': '7.3',
'KK.0': '10.00', 'KK.1': '90.0'}}
CodePudding user response:
from collections import defaultdict
new = defaultdict(dict)
for k, values in d.items():
for sub_key, values in values.items():
for value in values:
existing_key_count = sum(1 for existing_key in new[k].keys() if existing_key.startswith(sub_key))
new_key = f"{sub_key}.{existing_key_count}"
new[k][new_key] = value
{'Ka': {'Ka.0': '0.80', 'Ka.1': '0.1', 'Ba.0': '0.50', 'Ba.1': '1.1', 'FC.0': '0.78', 'FC.1': '0.0', 'AA.0': '0.66', 'AA.1': '8.1'}, 'AL': {'AR.0': '2.71', 'AR.1': '7.3', 'KK.0': '10.00', 'KK.1': '90.0'}}