我有一组任意的JSON数据,这些数据已在Python中解析为字典列表和深度不同的列表.我需要能够将其“扁平化”成字典列表.下面的例子:
源数据示例1
[{u'industry': [
{u'id': u'112', u'name': u'A'},
{u'id': u'132', u'name': u'B'},
{u'id': u'110', u'name': u'C'},
],
u'name': u'materials'},
{u'industry': {u'id': u'210', u'name': u'A'},
u'name': u'conglomerates'}
]
所需结果示例1
[{u'name':u'materials', u'industry_id':u'112', u'industry_name':u'A'},
{u'name':u'materials', u'industry_id':u'132', u'industry_name':u'B'},
{u'name':u'materials', u'industry_id':u'110', u'industry_name':u'C'},
{u'name':u'conglomerates', u'industry_id':u'210', u'industry_name':u'A'},
]
对于这个简单的示例来说,这很容易,但是我并不总是具有字典列表的确切结构,而且还有一层字典列表.在某些情况下,我可能需要遵循相同的方法进行其他嵌套.结果,我认为我将需要递归,而我似乎无法使它起作用.
拟议方法
1)对于每个Dicts列表,在每个键之前添加一个提供父键名称的“路径”.在上面的示例中,“ industry”是包含字典列表的键,因此列表中的每个子字典都添加了“ industry”.
2)将“父项”项添加到列表中的每个词典中-在这种情况下,“名称”和“行业”是字典的顶级列表中的项,因此将“名称”键/值添加到每个“行业”中的项目.
我可以想象一些情况,在“父项”项中有多个词典甚至是词典的词典,而将这些子树中的每一个应用于词典的子级列表将不起作用.因此,我将假定“父项”始终是简单的键/值对.
另一个示例试图说明需要处理的数据结构中的潜在差异.
源数据示例2
[{u'industry': [
{u'id': u'112', u'name': u'A'},
{u'id': u'132', u'name': u'B'},
{u'id': u'110', u'name': u'C', u'company': [
{u'id':'500', u'symbol':'X'},
{u'id':'502', u'symbol':'Y'},
{u'id':'504', u'symbol':'Z'},
]
},
],
u'name': u'materials'},
{u'industry': {u'id': u'210', u'name': u'A'},
u'name': u'conglomerates'}
]
所需结果示例2
[{u'name':u'materials', u'industry_id':u'112', u'industry_name':u'A'},
{u'name':u'materials', u'industry_id':u'132', u'industry_name':u'B'},
{u'name':u'materials', u'industry_id':u'110', u'industry_name':u'C',
u'company_id':'500', u'company_symbol':'X'},
{u'name':u'materials', u'industry_id':u'110', u'industry_name':u'C',
u'company_id':'502', u'company_symbol':'Y'},
{u'name':u'materials', u'industry_id':u'110', u'industry_name':u'C',
u'company_id':'504', u'company_symbol':'Z'},
{u'name':u'conglomerates', u'industry_id':u'210', u'industry_name':u'A'},
]
我看了其他几个例子,但似乎找不到在这些例子中有用的例子.
有什么建议或指示吗?我花了一些时间试图构建一个递归函数来处理这个问题,但是很多小时后却没有运气.
一次失败的更新
def _flatten(sub_tree, flattened=[], path="", parent_dict={}, child_dict={}):
if type(sub_tree) is list:
for i in sub_tree:
flattened.append(_flatten(i,
flattened=flattened,
path=path,
parent_dict=parent_dict,
child_dict=child_dict
)
)
return flattened
elif type(sub_tree) is dict:
lists = {}
new_parent_dict = {}
new_child_dict = {}
for key, value in sub_tree.items():
new_path = path + '_' + key
if type(value) is dict:
for key2, value2 in value.items():
new_path2 = new_path + '_' + key2
new_parent_dict[new_path2] = value2
elif type(value) is unicode:
new_parent_dict[key] = value
elif type(value) is list:
lists[new_path] = value
new_parent_dict.update(parent_dict)
for key, value in lists.items():
for i in value:
flattened.append(_flatten(i,
flattened=flattened,
path=key,
parent_dict=new_parent_dict,
)
)
return flattened
我得到的结果是“无”对象的231×231矩阵-显然我在递归运行中遇到了麻烦.
我尝试了一些其他的“从头开始”尝试,但均以类似的失败模式失败.