【问题标题】:How to create a tree using BFS in python?如何在 python 中使用 BFS 创建树?
【发布时间】:2021-05-25 09:44:22
【问题描述】:

所以我有一个像这样的 JSON 扁平树,作为对象数组:

[{
    aid: "id3",
    data: ["id1", "id2"]
},

{
    aid: "id1",
    data: ["id3", "id2"]
},

{
    aid: "id2",
    nested_data: {aid: "id4", atype: "nested", data: ["id1", "id3"]},
    data: []
}]

我想收集那棵树并通过递归循环将 id 解析为数据,就像这样(假设我们从 "id3" 开始):

{
   "aid":"id3",
   "payload":"1",
   "data":[
      {
         "id1":{
            "aid":"id1",
            "data":[
               {
                  "id3":null
               },
               {
                  "id2":null
               }
            ]
         }
      },
      {
         "id2":{
            "aid":"id2",
            "nested_data":{
               "aid":"id4",
               "atype":"nested",
               "data":[
                  {
                     "id1":null
                  },
                  {
                     "id3":null
                  }
               ]
            },
            "data":[
               
            ]
         }
      }
   ]
}

这样我们就可以进行广度优先搜索并在第一次进入时将某些字段解析为"value": "object with that field""value": Null

如何在 python 3 中做这样的事情?

【问题讨论】:

  • 您的输入 JSON 也是无效的。键需要用双引号括起来,键/值对应该用逗号分隔。不确定如何使用它。你有一些代码吗?
  • @trincot:请查看更新版本
  • 为什么输入中有bdata属性?有没有理由不叫data? (您没有回答此评论)为什么输入中有一个具有atype 属性的对象?为什么输出中有多个这样的属性?
  • 为什么bdata不是数组?如果有多个这样的嵌套依赖怎么办?
  • @trincot:巴士拉展示了一个嵌套数据对象的示例,其中包含要解包的数据子字段

标签: python json tree breadth-first-search


【解决方案1】:

除了您的结构在语法方面存在的所有问题(标识符必须在引号内等)之外,下面的代码将为您提供所需的答案。

但是你应该仔细考虑你在做什么,并考虑到以下几点:

  • 使用您提供的平面结构中表达的关系意味着您将有无限递归,因为您的项目包括其他项目,而其他项目又包括第一个项目(如 id3 包括 id1,其中转而包含id3。因此,您必须定义停止条件,或者确保这不会出现在您的平面结构中。
  • 您的初始扁平结构最好采用字典的形式,而不是对 {id, data} 的列表。这就是为什么下面的代码要做的第一件事就是转换它。
  • 就所包含的信息而言,您最终想要的结构包含大量冗余。考虑简化它。
  • 最后,您没有提及“nested_data”节点以及应如何处理它们。我只是假设如果存在,则需要进一步扩展。

请考虑尝试在您的问题中提供一些背景信息,一些真实数据示例(我认为提供的数据不是真实数据,因此存在不一致和冗余),并尝试自己并提供您的努力;这是学习的唯一途径。

from pprint import pprint

def reformat_flat_info(flat):
    reformatted = {}
    for o in flat:
        key = o["aid"]
        del o["aid"]
        reformatted[key] = o
    return reformatted

def expand_data(aid, flat, lvl=0):
    obj = flat[aid]
    if obj is None: return {aid: obj}

    obj.update({"aid": aid})
    if lvl > 1:
        return {aid: None}

    for nid,id in enumerate(obj["data"]):
        obj["data"][nid] = expand_data(id, flat, lvl=lvl+1)

    if "nested_data" in obj:
        for nid,id in enumerate(obj["nested_data"]["data"]):
            obj["nested_data"]["data"][nid] = expand_data(id, flat, lvl=lvl+1)

    return {aid: obj}

# Provide the flat information structure
flat_info = [
    {
        "aid": "id3",
        "data": ["id1", "id2"]
    }, {
        "aid": "id1",
        "data": ["id3", "id2"]
    }, {
        "aid": "id2",
        "nested_data": {"aid": "id4", "atype": "nested", "data": ["id1", "id3"]},
        "data": []
    }
]
pprint(flat_info)
print('-'*80)

# Reformat the flat information structure
new_flat_info = reformat_flat_info(flat=flat_info)
pprint(new_flat_info)
print('-'*80)

# Generate the result
starting_id = "id3"
result = expand_data(aid=starting_id, flat=new_flat_info)
pprint(result)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 1970-01-01
    • 2011-07-02
    • 1970-01-01
    • 1970-01-01
    • 2018-09-05
    • 1970-01-01
    相关资源
    最近更新 更多