我使用anytree
生成了这样的树:
A
├── B
│ └── C
│ └── D
│ └── F
└── B
└── C
└── E
└── G
是否有方法删除所有重复的子项并将其转换为下面的树(对于所有可能级别的子项都是递归的)?
A
└── B
└── C
├── D
| └── F
└── E
└── G
编辑:
我试图实现的是一个网站上所有链接的树。所以斜杠之间的所有内容都将成为子项:
.../child/...
(第二个斜杠是可选的)。以上只是我问题的一个表现,但我希望它是清楚的。以下是我的节点生成:
root = Node('A')
for link in links:
children = link.split('/')
cur_root = Node(children[0], parent=root)
for one in children[1:]:
cur_root = Node(one, parent=cur_root)
最佳答案
问题是,每次添加新链接时,都会添加从根节点到最后一个子节点的新节点序列。但是,您已经部分地添加了这样一条路径,这是绝对可能的(而且似乎是合理的)。
一个快速的解决方法是简单地检查一个子节点是否已经添加到节点中,并且只有在没有添加到节点中时才进行比如:
root = Node('A')
for link in links:
node = root
for child in link.split('/'):
sub = next((c for c in node.children if c.name == child),None)
if sub is None:
sub = Node(child,parent=node)
node = sub
因此,对于每个
link in links
,我们最初将node
设置为root
然后,对于每个child
节点,我们将首先搜索具有相同名称的子节点如果我们能找到这样一个孩子(sub
不是None
),我们就构造一个新的孩子。不管节点是否已经是子节点,我们都会移动到子节点,直到链接结束。这将确保树中没有(部分)重复的路径,而且它将减少它使用的内存量,因为将构造更少的对象(从而减少存储在内存中的对象)。