【问题标题】:Selective flattening of JSON in PythonPython中JSON的选择性展平
【发布时间】:2020-05-03 08:53:03
【问题描述】:

我正在从返回非标准化 json 的 API 中提取数据,这意味着我必须编写一个自定义函数来解析每个数据流,因为 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,以及如何访问其中的特定项目的“路线图”,然后返回指定项目的平面列表。

上一个示例的路线图及其用法如下所示:

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 循环。

感谢您的帮助!

【问题讨论】:

  • 您在解析 JSON 时遇到问题,还是这只是另一个根本与 JSON 无关的问题?
  • 也许做一个递归函数来首先识别键和它们的层次结构,然后一个一个地遍历它们?
  • @HeapOverflow 解析 JSON 没有问题,问题在于创建一个通用函数来解析具有不同字典和列表嵌套结构的不同数据流。
  • 哦等等,这甚至不是 JSON。是的,还有一个与 JSON 无关的“JSON 问题”。
  • 因为您已经过了 JSON 阶段。你只有一个 Python 数据结构问题。

标签: python json hierarchical-data flatten


【解决方案1】:
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]}
]

【讨论】:

    猜你喜欢
    • 2012-10-16
    • 2017-02-02
    • 2018-02-11
    • 2022-06-21
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-20
    相关资源
    最近更新 更多