示例字典:
flat = {'X_a_one': 10,
'X_a_two': 20,
'X_b_one': 10,
'X_b_two': 20,
'Y_a_one': 10,
'Y_a_two': 20,
'Y_b_one': 10,
'Y_b_two': 20}
嵌套字典:
nested = {'X': {'a': {'one': 10,
'two': 20},
'b': {'one': 10,
'two': 20}},
'Y': {'a': {'one': 10,
'two': 20},
'b': {'one': 10,
'two': 20}}}
1、使用自定义函数实现
def nest_dict(flat): result = {} for k, v in flat.items(): _nest_dict_rec(k, v, result) return result def _nest_dict_rec(k, v, out): k, *rest = k.split('_', 1) if rest: _nest_dict_rec(rest[0], v, out.setdefault(k, {})) else: out[k] = v flat = {'X_a_one': 10, 'X_a_two': 20, 'X_b_one': 10, 'X_b_two': 20, 'Y_a_one': 10, 'Y_a_two': 20, 'Y_b_one': 10, 'Y_b_two': 20} print(nest_dict(flat))
2、使用for循环实现
output = {} source = {'X_a_one': 10, 'X_a_two': 20, 'X_b_one': 10, 'X_b_two': 20, 'Y_a_one': 10, 'Y_a_two': 20, 'Y_b_one': 10, 'Y_b_two': 20} for k, v in source.items(): current = output pieces = k.split('_') for piece in pieces[:-1]: if not piece in current: current[piece] = {} current = current[piece] current[pieces[-1]] = v print(output)
3、使用collections.defaultdict实现
from collections import defaultdict from functools import reduce from operator import getitem def getFromDict(dataDict, mapList): """Iterate nested dictionary""" return reduce(getitem, mapList, dataDict) # instantiate nested defaultdict of defaultdicts tree = lambda: defaultdict(tree) d = tree() flat = {'X_a_one': 10, 'X_a_two': 20, 'X_b_one': 10, 'X_b_two': 20, 'Y_a_one': 10, 'Y_a_two': 20, 'Y_b_one': 10, 'Y_b_two': 20} # iterate input dictionary for k, v in flat.items(): *keys, final_key = k.split('_') getFromDict(d, keys)[final_key] = v print(d) #最后一步,可以将defaultdict转换为常规dict,可能这一步有时没有必要。 def default_to_regular_dict(d): """Convert nested defaultdict to regular dict of dicts.""" if isinstance(d, defaultdict): d = {k: default_to_regular_dict(v) for k, v in d.items()} return d # 转换回常规字典 res = default_to_regular_dict(d) print(res)