【问题标题】:Parse json response to get parent/child dictionary解析 json 响应以获取父/子字典
【发布时间】:2018-05-03 19:58:47
【问题描述】:

我有一个我正在尝试解析的 json 列表(最初是来自 TestRail API getcases 的响应)。这是一个示例 json:

[
{
    "id": 1,
    "parent_id": null,
},
{
    "id": 2,
    "parent_id": 1,
},
{
    "id": 6,
    "parent_id": null,
},
{
    "id": 16,
    "parent_id": 2,
},
{
    "id": 7,
    "parent_id": 1,
},
{
    "id": 3,
    "parent_id": 6
}
]

我想做的是找出哪些 ID 属于原始父 ID。 例如id:1"id": 6, 是自"parent_id": null 以来最顶层的父节点。

我想让所有子节点都属于最顶层的父节点。 在这个例子中,这里是基于parent_id的关系

1 -> [2,7] -> 16

6 -> 3

主要目标是确定顶级父节点的所有子(和子)节点是什么。我对了解子父/子关系不感兴趣。

我要解析的是得到以下输出:

{
 1: [2,7,16],
 6: 3
}

一种方法是使用几个嵌套的 for 循环,为每个顶级父节点检查它是否显示为 parent_id 并递归地使用它,但这看起来不是一个很好的方法。

不胜感激任何 cmets/建议

【问题讨论】:

  • 读取所有节点,将它们作为连接添加到图上,然后从每个没有父节点的节点执行 bfs/dfs 以了解它可以到达的所有节点

标签: python algorithm testrail


【解决方案1】:
import json

from collections import defaultdict

data = json.loads(
    '[{"id": 1, "parent_id": null}, {"id": 2, "parent_id": 1}, {"id": 6, "parent_id": null}, {"id": 16, "parent_id": 2}, {"id": 7, "parent_id": 1}, {"id": 3, "parent_id": 6}]')

parents = {d['id']: d['parent_id'] for d in data}

class RootsDict(dict):
    def __missing__(self, key):
        parent = parents[key]
        if parent is None:
            return key
        else:
            return self[parent]

roots_dict = RootsDict()
descendants = defaultdict(list)

for d in data:
    id_ = d['id']
    if d['parent_id'] is not None:
        descendants[roots_dict[id_]].append(id_)

print(descendants)  # {1: [2, 16, 7], 6: [3]}

roots_dict 被设计成roots_dict[node] 将返回node 的顶级父级,如果它已经是根,则返回node 本身。 __missing__ 是一种可以被 dicts 覆盖的特殊方法。当从 dict 请求 key 但不存在时调用它。无论方法返回什么,都将被放置在该值的字典中。因此,例如roots_dict[16] 第一次访问时将设置为等于roots_dict[2],这反过来会要求roots_dict[1],即1。其余的都很简单。

【讨论】:

    猜你喜欢
    • 2019-10-11
    • 1970-01-01
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多