我正试图从我拥有的字符串列表中构建一个层次结构图。每个字符串只是由点分隔的绝对层次结构组成。字符串示例:
memberA.memberB.memberC
memberA.memberE.memberG
memberA.memberE
memberA.memberB
memberA.memberF.memberX
memberA.memberF
memberA.memberF.memberG #in this case this should be treated as a seperate leaf node and not the same as in memberA.memberE.memberG
我尝试使用Anytree和Treelib来实现这一点,但我无法提出一个工作的解决方案。虽然这个问题看起来很简单,但我就是想不出来。
您需要跟踪哪些节点对象对应于某个路径。为此,您可以使用字典,它将给定路径映射到节点对象。
对于AnyTree,它可能看起来像这样:
from anytree import Node, RenderTree
strings = [
"memberA.memberB.memberC",
"memberA.memberE.memberG",
"memberA.memberE",
"memberA.memberB",
"memberA.memberF.memberX",
"memberA.memberF",
"memberA.memberF.memberG"
]
d = {}
root = Node("root")
for s in strings:
path = "root"
parent = root
for name in s.split("."):
path += "." + name
if path not in d:
d[path] = Node(name, parent=parent)
parent = d[path]
print(RenderTree(root))
输出:
Node('/root')
└── Node('/root/memberA')
├── Node('/root/memberA/memberB')
│ └── Node('/root/memberA/memberB/memberC')
├── Node('/root/memberA/memberE')
│ └── Node('/root/memberA/memberE/memberG')
└── Node('/root/memberA/memberF')
├── Node('/root/memberA/memberF/memberX')
└── Node('/root/memberA/memberF/memberG')
如果你想要"memberA"要作为根,那么您需要确保您的输入数据只有以"memberA"开头的字符串。然后在上述脚本的末尾执行:
root = root.children[0]
root.parent = None
print(RenderTree(root))
输出:
Node('/memberA')
├── Node('/memberA/memberB')
│ └── Node('/memberA/memberB/memberC')
├── Node('/memberA/memberE')
│ └── Node('/memberA/memberE/memberG')
└── Node('/memberA/memberF')
├── Node('/memberA/memberF/memberX')
└── Node('/memberA/memberF/memberG')