使用Python将深层嵌套字典转换为1D字典
问题描述:
我有一些深度随机嵌套字典,如下所示。使用Python将深层嵌套字典转换为1D字典
{'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', ...
我该如何将它转换成1D字典如下。
dict["CompilationStatistics_CodeGeneration_EndTime"] = '2010-04-21T14:03:11' dict["CompilationStatistics_CodeGeneration_StartTime"] = '2010-04-21T14:03:11' ... dict["CompilationStatistics_directory] = "/abc"
答
简单的是做递归:
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
下面是一个例子使用:
d = {'foo': 'bar',
'baz': {'fie': 'foo', 'zip': 'zap'},
'bam': {'fie': 'foo', 'zip': {'zap': 'zup', 'mep': 'mop'}},
}
print flattendict(d)
p (可能,当然,按不同顺序)
{'baz_zip': 'zap', 'bam_fie': 'foo', 'foo': 'bar', 'bam_zip_mep': 'mop',
'baz_fie': 'foo', 'bam_zip_zap': 'zup'}
答
哼哼,有趣......
这是一个递归函数的绝佳机会。这里有一个,据我的初步测试,将做的工作:
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)