有时候,我们可能会遇到一些深度嵌套的字典,需要将其转换为一维字典。例如,以下是一个深度嵌套的字典:
{'CompilationStatistics': {'CodeGeneration': {'EndTime': '2010-04-21T14:03:11',
'StartTime': '2010-04-21T14:03:11',
'StepList': {'EliminatingDuplicates': {'EndTime': '2010-04-21T14:03:11',
'NumberOfFilesEliminated': '14',
'StartTime': '2010-04-21T14:03:11'},
'ModuleGenerator': {'EndTime': '2010-04-21T14:03:11',
'StartTime': '2010-04-21T14:03:11'},
'Munger': {'EndTime': '2010-04-21T14:03:11',
...
我们需要将其转换为以下一维字典:
dict["CompilationStatistics_CodeGeneration_EndTime"] = '2010-04-21T14:03:11'
dict["CompilationStatistics_CodeGeneration_StartTime"] = '2010-04-21T14:03:11'
...
dict["CompilationStatistics_directory] = "/abc"
2、解决方案
我们可以使用递归的方法来完成这个任务。这里提供三种不同的递归方法:
方法一:
import collections
def flattendict(d, prefix=()):
r = {}
for k, v in d.iteritems():
pk = prefix + (k,)
if isinstance(v, collections.Mapping):
r.update(flattendict(v, pk))
else:
r['_'.join(pk)] = v
return r
方法二:
def convert(dct_in, dct_out=None, prefix='', sep='_'):
if dct_out is None:
dct_out = {}
if prefix:
prefix += sep
for k, v in dct_in.iteritems():
k_str = prefix + k
if isinstance(v, dict):
convert(v, dct_out, k_str, sep)
else:
dct_out[k_str] = v
return dct_out
方法三:
def flatten_dict(d):
subdicts = (([(k+"_"+k2, v2) for k2,v2 in flatten_dict(v).iteritems()]
if isinstance(v, dict)
else [(k,v)])
for k,v in d.iteritems())
return dict((k,v) for sd in subdicts for k,v in sd)
以上三种方法都可以将深度嵌套的字典转换为一维字典。我们可以根据自己的需要选择其中一种方法来使用。
代码例子:
d = {'CompilationStatistics': {'CodeGeneration': {'EndTime': '2010-04-21T14:03:11',
'StartTime': '2010-04-21T14:03:11',
'StepList': {'EliminatingDuplicates': {'EndTime': '2010-04-21T14:03:11',
'NumberOfFilesEliminated': '14',
'StartTime': '2010-04-21T14:03:11'},
'ModuleGenerator': {'EndTime': '2010-04-21T14:03:11',
'StartTime': '2010-04-21T14:03:11'},
'Munger': {'EndTime': '2010-04-21T14:03:11',
...
# 使用方法一
print(flattendict(d))
# 使用方法二
print(convert(d))
# 使用方法三
print(flatten_dict(d))
以上代码将输出如下结果:
{'CompilationStatistics_CodeGeneration_EndTime': '2010-04-21T14:03:11', 'CompilationStatistics_CodeGeneration_StartTime': '2010-04-21T14:03:11', ...}
{'CompilationStatistics_CodeGeneration_EndTime': '2010-04-21T14:03:11', 'CompilationStatistics_CodeGeneration_StartTime': '2010-04-21T14:03:11', ...}
{'CompilationStatistics_CodeGeneration_EndTime': '2010-04-21T14:03:11', 'CompilationStatistics_CodeGeneration_StartTime': '2010-04-21T14:03:11', ...}