Python 中 JSON 的选择性扁平化
Selective flattening of JSON in Python
我正在从 API 中提取数据,其中 returns 是非标准化的 json,这意味着我必须编写一个自定义函数来解析每个数据流,因为 JSON 具有嵌套字典和列表的不同结构。我想要的输出是一个包含所有相关端点项的扁平化列表。我已经为其中一些编写了函数,但我正在尝试创建更通用的东西。
示例 JSON 的形式为:
JSON = {
'metadata' : {
'meta_param' : 'meta_value',
},
'contents' : [
{
'content' : [
{
'attributes' : {
'series_name' : 'series_1a',
},
'data' : {
'index' : [0, 1, 2, 3, 4, 5],
'values' : [12, 84, 38, 3, 92, 67]
},
},
{
'attributes' : {
'series_name' : 'series_2a',
},
'data' : {
'index' : [0, 1, 2, 3, 4, 5],
'values' : [42, 73, 48, 20, 19, 61]
},
},
],
},
{
'content' : [
{
'attributes' : {
'series_name' : 'series_1b',
},
'data' : {
'index' : [0, 1, 2, 3, 4, 5],
'values' : [13, 85, 39, 4, 93, 68]
},
},
{
'attributes' : {
'series_name' : 'series_2b',
},
'data' : {
'index' : [0, 1, 2, 3, 4, 5],
'values' : [43, 74, 49, 21, 20, 62]
},
},
],
},
]
}
然后我会编写一个这样的自定义函数来将其转换为平面列表
flatlist = []
for contents in JSON['contents']:
for content in contents['content']:
flatlist.append(content['data'])
flatlist ->
[{'index': [0, 1, 2, 3, 4, 5], 'values': [12, 84, 38, 3, 92, 67]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [42, 73, 48, 20, 19, 61]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [13, 85, 39, 4, 93, 68]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [43, 74, 49, 21, 20, 62]}]
我正在尝试创建一个函数,它接受 JSON 嵌套字典和列表,以及 'routemap' 如何访问其中的特定项目,然后 returns 指定项目的平面列表。
前面示例中的路线图及其用法如下所示:
JSON_route = [
'contents',
'content',
'data',
]
flatlist = json_to_flatlist(JSON, JSON_route)
flatlist ->
[{'index': [0, 1, 2, 3, 4, 5], 'values': [12, 84, 38, 3, 92, 67]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [42, 73, 48, 20, 19, 61]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [13, 85, 39, 4, 93, 68]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [43, 74, 49, 21, 20, 62]}]
我的关键问题是我不确定如何以编程方式将 JSON_route 列表转换为提取数据所需的嵌套 for 循环。
感谢您的帮助!
def json_to_flatlist(obj, route):
if len(route) == 0:
yield obj
elif isinstance(obj, list):
for item in obj:
yield from json_to_flatlist(item, route)
else:
yield from json_to_flatlist(obj[route[0]], route[1:])
JSON_route = [
'contents',
'content',
'data',
]
result = list(json_to_flatlist(JSON, JSON_route))
print(result)
结果(为清楚起见添加了换行符):
[
{'index': [0, 1, 2, 3, 4, 5], 'values': [12, 84, 38, 3, 92, 67]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [42, 73, 48, 20, 19, 61]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [13, 85, 39, 4, 93, 68]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [43, 74, 49, 21, 20, 62]}
]
我正在从 API 中提取数据,其中 returns 是非标准化的 json,这意味着我必须编写一个自定义函数来解析每个数据流,因为 JSON 具有嵌套字典和列表的不同结构。我想要的输出是一个包含所有相关端点项的扁平化列表。我已经为其中一些编写了函数,但我正在尝试创建更通用的东西。
示例 JSON 的形式为:
JSON = {
'metadata' : {
'meta_param' : 'meta_value',
},
'contents' : [
{
'content' : [
{
'attributes' : {
'series_name' : 'series_1a',
},
'data' : {
'index' : [0, 1, 2, 3, 4, 5],
'values' : [12, 84, 38, 3, 92, 67]
},
},
{
'attributes' : {
'series_name' : 'series_2a',
},
'data' : {
'index' : [0, 1, 2, 3, 4, 5],
'values' : [42, 73, 48, 20, 19, 61]
},
},
],
},
{
'content' : [
{
'attributes' : {
'series_name' : 'series_1b',
},
'data' : {
'index' : [0, 1, 2, 3, 4, 5],
'values' : [13, 85, 39, 4, 93, 68]
},
},
{
'attributes' : {
'series_name' : 'series_2b',
},
'data' : {
'index' : [0, 1, 2, 3, 4, 5],
'values' : [43, 74, 49, 21, 20, 62]
},
},
],
},
]
}
然后我会编写一个这样的自定义函数来将其转换为平面列表
flatlist = []
for contents in JSON['contents']:
for content in contents['content']:
flatlist.append(content['data'])
flatlist ->
[{'index': [0, 1, 2, 3, 4, 5], 'values': [12, 84, 38, 3, 92, 67]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [42, 73, 48, 20, 19, 61]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [13, 85, 39, 4, 93, 68]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [43, 74, 49, 21, 20, 62]}]
我正在尝试创建一个函数,它接受 JSON 嵌套字典和列表,以及 'routemap' 如何访问其中的特定项目,然后 returns 指定项目的平面列表。
前面示例中的路线图及其用法如下所示:
JSON_route = [
'contents',
'content',
'data',
]
flatlist = json_to_flatlist(JSON, JSON_route)
flatlist ->
[{'index': [0, 1, 2, 3, 4, 5], 'values': [12, 84, 38, 3, 92, 67]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [42, 73, 48, 20, 19, 61]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [13, 85, 39, 4, 93, 68]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [43, 74, 49, 21, 20, 62]}]
我的关键问题是我不确定如何以编程方式将 JSON_route 列表转换为提取数据所需的嵌套 for 循环。
感谢您的帮助!
def json_to_flatlist(obj, route):
if len(route) == 0:
yield obj
elif isinstance(obj, list):
for item in obj:
yield from json_to_flatlist(item, route)
else:
yield from json_to_flatlist(obj[route[0]], route[1:])
JSON_route = [
'contents',
'content',
'data',
]
result = list(json_to_flatlist(JSON, JSON_route))
print(result)
结果(为清楚起见添加了换行符):
[
{'index': [0, 1, 2, 3, 4, 5], 'values': [12, 84, 38, 3, 92, 67]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [42, 73, 48, 20, 19, 61]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [13, 85, 39, 4, 93, 68]},
{'index': [0, 1, 2, 3, 4, 5], 'values': [43, 74, 49, 21, 20, 62]}
]