首页 > 解决方案 > 将树数据转换为 json

问题描述

我正在尝试将树结构中的数据保存到 json 中,但我很难做到。我的树节点有一个名字和一个子节点列表。

class Node:
    def __init__(self, name: str):
        self.name = name
        self.children = dict()

我正在运行 BFS 以尝试捕获结构但没有成功。我遇到的问题是我不知道如何在第一次迭代后添加孩子,因为所有字典键都是相同的“名称”和“孩子”

queue.put(root)
data = {}
while not queue.empty():
    node = queue.get()
    children = []
    data.update({"name": node.name, "children": children})
    for child in node.children:
        children.append({"name": node.children[child].name, "children": []})
        queue.put(node.children[child])

with open("test.json", "w") as f:
    json.dump(data, f, indent=4)

使用当前代码,我无法将项目添加到结果字典中,因为我每次迭代都使用相同的键。第二次迭代将删除第一次迭代中的条目。另外,我不知道如何在后续迭代中引用子列表中的特定 dict。

这是当前的 result.json。只有最后一次迭代中的最后一个条目被保存

{
    "name": "ffff",
    "children": []
}

我不知道运行 BFS 是否是唯一的方法。也许还有其他更好更简单的方法来做到这一点?

例如,我想在最后达到这个预期的结果。然而,真正的树比这大得多。

{
    "name": "root",
    "children": [
        {
            "name": "aaaa",
            "children": [
                {
                    "name": "bbbb",
                    "children": [
                        {
                            "name": "cccc"
                            "children": []
                        }
                    ]
                }
        },
        {
            "name": "dddd",
            "children": [
                {
                    "name": "eeee",
                    "children": [
                        {
                            "name": "ffff"
                            "children": []
                        }
                    ]
                }
        }
}

我也试过直接做

json_file = json.dumps(root, indent=2)

但它给了我一个错误

TypeError: Object of type Node is not JSON serializable

标签: pythonjson

解决方案


我无法从您的代码中得出children字典中键的值是什么,但我猜它们是那些孩子的名字。

您可以使用 BFS 执行此操作,但使用 DFS 更容易。您的代码永远不会向下移动children您在其中创建的结构(通过)data,因此预计您不会得到嵌套输出。

但是,无论如何,这是一个 DFS 解决方案:

class Node:
    def __init__(self, name: str):
        self.name = name
        self.children = dict()

    # A method to easily add a child to this node:
    def add(self, child):
        self.children[child.name] = child
        return self

    # A method to return the current tree as a nested dictionary
    def to_dict(self):
        return {
            "name": self.name,
            "children": [child.to_dict() for child in self.children.values()]
        }

# Example: create the tree from the question
root = Node("root").add(
    Node("aaaa").add(
        Node("bbbb").add(
            Node("cccc")
        )
    )
).add(
    Node("dddd").add(
        Node("eeee").add(
            Node("ffff")
        )
    )
)

# Produce the JSON output
import json
print(json.dumps(root.to_dict(), indent=2))

推荐阅读