我正在尝试使用 python 从嵌套列表创建一个树可视化器,而不需要任何特殊的库。
我遇到的问题是,虽然树的节点存储正确,但它却按照输入的顺序打印出来。
我尝试实现此问题的递归解决方案,该解决方案适用于诸如
[42,['a','b']]
之类的输入 - 其中 42
是根节点,'a'
和 'b'
是其子节点。不过,我也可以接收像 [['a','b'], 42]
这样的输入,其中 42
仍然是根节点。代码、示例输出如下。
这是我尝试实施的解决方案。
class TreeNode:
def __init__(self, data):
self.data = data
self.children = []
def add_child(self, child_node):
self.children.append(child_node)
def assign_tree_nodes(input_data):
if isinstance(input_data, list):
node = TreeNode(None)
for item in input_data:
child_node = assign_tree_nodes(item)
node.add_child(child_node)
return node
else:
return TreeNode(input_data)
def print_tree(node, indent=0):
if node.data is not None:
print(" " * indent + str(node.data))
if node.children:
for child in node.children:
print_tree(child, indent + 1)
# Prompt the user for input
input_data = eval(input("INPUT:\n"))
# Assign tree nodes
root_node = assign_tree_nodes(input_data)
# Print out the tree
for child in root_node.children:
print_tree(child)
此给定代码适用于诸如
[42,['a,'b']]
之类的输入,其中输出为
42
a
b
但是对于像
[['a','b'],42]
这样的输入,输出是
a
b
42
我稍微研究了一下你的代码,发现实际发生的情况是“根节点”具有
None
的数据,而看起来节点的数据实际上是一个有数据集但没有子节点的子节点。
您可能想要的是:
def add_child(self, child_node):
if child_node.data is not None and child_node.children == []:
# whoops, it's a leaf
self.data = child_node.data
else:
self.children.append(child_node)
如果您知道您的输入始终是 2 元素列表,并且最多有一个子列表指示子列表,那么这将起作用。
在类似 @trincot 的示例
[['a', [9], 'b'],42]
的情况下,根据这是否有意义,您可能需要做的就是这样做,以确保叶节点始终在子列表中首先列出:
def add_child(self, child_node):
if child_node.data:
# it's a leaf so it comes first
self.children.insert(0, child_node)
else:
# it's a branch node
self.children.append(child_node)
随你挑选。或者也许其他人会发布另一个答案。