【问题标题】:How can I convert a list of dicts showing hierarchical relationships into a tree?如何将显示层次关系的字典列表转换为树?
【发布时间】:2021-09-21 03:41:45
【问题描述】:

我有这个字典列表:

[
    {"node": "root", "children": ["a"]},
    {"node": "a", "children": ["b", "b"]},
    {"node": "b", "children": ["c", "c", "c"]},
    {"node": "c", "children": ["d"]},
]

表示压缩树。我的意思是这个 dict 列表代表以下树:

我可以将这个 dict 列表转换成什么样的数据结构,以便我可以将它展开成树?我正在考虑将字典列表展开为:

{"root": [
    {"a": [
        {"b": [
            {"c": [
                {"d": "None"}
              ]
            },
            {"c": [
                {"d": "None"}
              ]
            },
            {"c": [
                {"d": "None"}
              ]
            }
          ]
        },
        {"b": [
            {"c": [
                {"d": "None"}
              ]
            },
            {"c": [
                {"d": "None"}
              ]
            },
            {"c": [
                {"d": "None"}
              ]
            }
          ]
        }
      ]
    }
  ]
}

看起来很乱,但本质上是子节点列表的嵌套字典。不太确定如何实现这一目标。欢迎任何其他解压缩此树的想法!

理想情况下,我可以将其放入诸如treelib 之类的树库中,以获取列出叶节点、访问父母、祖父母等数据的方法。

【问题讨论】:

  • 我认为它只需要一个 for-loop 就可以转换它,而且你可以在没有任何外部模块的情况下完成它。

标签: python data-structures tree hierarchical-data


【解决方案1】:

首先,我会转换这个:

l = [
    {"node": "root", "children": ["a"]},
    {"node": "a", "children": ["b", "b"]},
    {"node": "b", "children": ["c", "c", "c"]},
    {"node": "c", "children": ["d"]},
]

转换成更可行的格式:

compressed = {e["node"]: e["children"] for e in l}

那么就很简单了:

def expand(compressed, root):
    children = [expand(compressed, n) for n in compressed.get(root, [])]
    return {root: children or "None"}

在你的例子中:

>>> from pprint import pprint
>>> pprint(expand(compressed, "root"))
{'root': [{'a': [{'b': [{'c': [{'d': 'None'}]},
                        {'c': [{'d': 'None'}]},
                        {'c': [{'d': 'None'}]}]},
                 {'b': [{'c': [{'d': 'None'}]},
                        {'c': [{'d': 'None'}]},
                        {'c': [{'d': 'None'}]}]}]}]}

也就是说,我建议不要用字符串 "None" 替换空子列表,而是将其替换为空列表(因此只需删除上面的 or "None")。

【讨论】:

  • 这是一种非常优雅的递归方法!我的树将附加附加到节点的属性,因此您的解决方案只需要稍作修改,谢谢!
  • @room_temperature 与树有关的任何事情几乎总是递归更容易。树是递归的母语。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-24
  • 1970-01-01
  • 2014-01-30
  • 2016-01-16
相关资源
最近更新 更多