从列表列表中打印出python中的缩进节点树

时间:2015-11-16 18:07:02

标签: python python-2.7

我的数据集格式为[node_id,name,parent_node_id]。我想输出一个缩进的节点树。我已经能够完成第一代,但不知道如何继续迭代列表。我不得不使用try / except子句,因为并非所有子列表都附加了它们的生成,因为我无法保持循环。

Grandparent
    Parent 1
    Parent 2
        Child 1
        Child 2

代码:

# establish data set in the format of [node_id, name, parent_node_id]
tree_info = [['5', 'Child 2', '3'],
             ['1', 'Grandparent', 'root'],
             ['4', 'Child 1', '3'], 
             ['3', 'Parent 2', '1'],
             ['2', 'Parent 1', '1']
             ]

# establish root node
root = [x[0] for x in tree_info if x[2] == 'root'][0]


# assign root node a generation of 0
tree_info[0].append(0)

# loop through
for node in tree_info:
    node_id = node[0]
    node_parent_id = node[2]
    if node_parent_id == root:
        # assign a generation of 1
        node.append(1)

for node in tree_info:
    try:
        print node[3] * " ", node[2]
    except:
        print "help"

1 个答案:

答案 0 :(得分:2)

正如评论中所建议的那样,您正在使用的数据结构对于树数据来说有些笨拙。尽管如此,打印出树的结构非常简单,前提是您要跟踪到目前为止看到的节点的缩进级别。我们可以用字典做到这一点:

# establish data set in the format of [node_id, name, parent_node_id]
tree_info = [
    ['1', 'Grandparent', 'root'], 
    ['2', 'Parent 1', '1'], 
    ['3', 'Parent 2', '1'], 
    ['4', 'Child 1', '3'], 
    ['5', 'Child 2', '3']
]

generation = {'root': 0}

for node in tree_info:
    node_id, name, parent_id = node
    indent = generation[parent_id]
    generation[node_id] = indent + 1
    print(indent * ' ' + name)

哪个收益率:

Grandparent
 Parent 1
 Parent 2
  Child 1
  Child 2

如果节点出现故障......

如果节点出现故障,我们需要读取一次数据以组装儿童字典。然后我们在字典上进行树搜索:

tree_info = [['5', 'Child 2', '3'],
             ['1', 'Grandparent', 'root'],
             ['4', 'Child 1', '3'], 
             ['3', 'Parent 2', '1'],
             ['2', 'Parent 1', '1'],
             ['6', 'Child 3', '2']
             ]

children = {}
names = {}

for node_id, name, parent in tree_info:
    children.setdefault(parent, []).append(node_id)
    names[node_id] = name

q = [('root', -1)]
while q:
    parent, depth = q.pop()
    if parent != 'root':
        print(' ' * depth + names[parent])

    if parent in children:
        for child in children[parent]:
            q.append((child, depth+1))

这会产生:

Grandparent
 Parent 1
  Child 3
 Parent 2
  Child 1
  Child 2

如果您希望每个级别按字母顺序排列

tree_info = [['5', 'A - Child 2', '3'],
             ['1', 'Grandparent', 'root'],
             ['4', 'B - Child 1', '3'], 
             ['3', 'A - Parent 2', '1'],
             ['2', 'B - Parent 1', '1'],
             ['6', 'C - Child 3', '2']
             ]

children = {}
names = {}

for node_id, name, parent in tree_info:
    children.setdefault(parent, []).append(node_id)
    names[node_id] = name

q = [('root', -1)]
while q:
    parent, depth = q.pop()
    if parent != 'root':
        print(' ' * depth + names[parent])

    if parent in children:
        level = sorted(children[parent], key=names.get)
        for child in reversed(level):
            q.append((child, depth+1))

打印哪些:

Grandparent
 A - Parent 2
  A - Child 2
  B - Child 1
 B - Parent 1
  C - Child 3