首页 > 解决方案 > 展平 JSON / 字典 / 列表

问题描述

我有一个嵌套的 JSON

{
    "ID": 300,
    "Name": " TEST",
    "Value": [
        {
            "Details": [
                {
                    "Name": "TEST1",
                    "Value": "XXXXXX"
                },
                {
                    "Name": "TEST2",
                    "Value": "DDDDDDDD"
                }
            ],
            "Time": [ 1600358400, 1600358700, 1600359000],
            "Values": [ 0, 0, 0]
        }
    ]
}

我想展平 json 以便能够获得类似的列表

在此处输入图像描述

我使用了 itertools groupby 但无法达到预期的结果。它水平变平。

到目前为止我尝试过的代码

from itertools import groupby
import json

def myflatten(d, depth=0):
    rv = [({}, depth)]
    if isinstance(d, dict):
        for k, v in d.items():
            if not isinstance(v, dict) and not isinstance(v, list):
                for i in rv:
                    i[0][k] = v
            else:
                for (vv, _depth) in myflatten(v,depth+1):
                    rv.append((rv[-1][0].copy(), _depth))
                    for kkk, vvv in vv.items():
                        rv[-1][0][kkk] = vvv
    elif isinstance(d, list):
        for v in d:
            rv.append((rv[-1][0].copy(), depth+1))
            for (vv, _) in myflatten(v,depth+1):
                for kkk, vvv in vv.items():
                    rv[-1][0][kkk] = vvv
    for i, _depth in rv:
        yield i, _depth

out = []

a = {
    "ID": 300,
    "Name": " TEST",
    "Value": [
        {
            "Details": [
                {
                    "Name": "TEST1",
                    "Value": "XXXXXX"
                },
                {
                    "Name": "TEST2",
                    "Value": "DDDDDDDD"
                }
            ],
            "Time": [ 1600358400, 1600358700, 1600359000],
            "Values": [ 0, 0, 0]
        }
    ]
}

for v, g in groupby(sorted(myflatten(a), key=lambda k: -k[1]), lambda k: k[1]):
    out.extend(i[0] for i in g)
    break
print(out)

有人可以帮助垂直而不是水平地展平嵌套的 json/dict/list 吗?最终目标是能够将数据存储在 RDBMS 中,而不必无限增加列数,而是增加行数。

标签: pythonjsonnestedflatten

解决方案


由于在您的情况下,您需要将行(或记录)存储在数据库中,因此您可以拥有一个生成字典列表的函数,您可以迭代地将其添加到数据库中。此外,由于您的代码似乎过于嵌套,您可以考虑以下代码片段:

def flatten(dictionary):
    my_list = []
    _id = dictionary["id"]
    name = dictionary["Name"]

    for obj in dictionary["Value"]:
        details = obj["Details"]
        time = obj["Time"]
        vals = obj["Values"]

        for i in range(len(time)):
            for (index, detail_obj) in enumerate(details):
                my_list.append({
                    "ID": _id,
                    "Name": name,
                    "Details.ID": index,
                    "Details.Name": detail_obj["Name"]
                    "Details.Value": detail_obj["Value"],
                    "Time.ID": i,
                    "Time.Time": time[i],
                    "Time.Value": vals[i]
                })

    return my_list

注意:此函数将一次处理一个嵌套字典(如您在问题中提供的字典)。因此,如果您有多个这样的嵌套字典,您可能希望为每个嵌套字典调用此函数。


推荐阅读