代码之家  ›  专栏  ›  技术社区  ›  BPL

如何在python中显示类似msdos tree命令的树?

  •  2
  • BPL  · 技术社区  · 6 年前

    import sys
    
    
    dct = {
        -1: [0, 60000],
        0: [100, 20],
        100: [30],
        30: [400, 500],
        60000: [70, 80]
    }
    
    
    def ptree(parent, tree, indent=''):
        print(parent)
        if parent not in tree:
            return
    
        for child in tree[parent][:-1]:
            print(indent + '|' + '-' * 4, end='')
            ptree(child, tree, indent + '|' + ' ' * 4)
        child = tree[parent][-1]
        print(indent + '`' + '-' * 4, end='')
        ptree(child, tree, indent + '  ' * 4)
    
    
    ptree(-1, dct)
    

    这个小代码有两个问题:

    • 在本文中,Item-1被认为是“不可见的根项”,因此我不想打印它
    • 这个命令的输出非常难看,而且对齐也不好,我想得到一个与 tree

    为了解决第一个要点,我考虑在代码中引入这些丑陋的条件/黑客:

    def ptree(parent, tree, indent=''):
        if parent != -1:
            print(parent)
        if parent not in tree:
            return
    
        for child in tree[parent][:-1]:
            if parent != -1:
                print(indent + '|' + '-' * 4, end='')
                ptree(child, tree, indent + '|' + ' ' * 4)
            else:
                ptree(child, tree, indent)
        child = tree[parent][-1]
        if parent != -1:
            print(indent + '`' + '-' * 4, end='')
            ptree(child, tree, indent + '  ' * 4)
        else:
            ptree(child, tree, indent)
    

    enter image description here

    问题

    2 回复  |  直到 6 年前
        1
  •  2
  •   Darkonaut    6 年前

    经过反复尝试,我终于找到了一个解决方案,似乎能准确地说出原始树产生的结果:

    def ptree(start, tree, indent_width=4):
    
        def _ptree(start, parent, tree, grandpa=None, indent=""):
            if parent != start:
                if grandpa is None:  # Ask grandpa kids!
                    print(parent, end="")
                else:
                    print(parent)
            if parent not in tree:
                return
            for child in tree[parent][:-1]:
                print(indent + "├" + "─" * indent_width, end="")
                _ptree(start, child, tree, parent, indent + "│" + " " * 4)
            child = tree[parent][-1]
            print(indent + "└" + "─" * indent_width, end="")
            _ptree(start, child, tree, parent, indent + " " * 5)  # 4 -> 5
    
        parent = start
        _ptree(start, parent, tree)
    
    
    dct = {
        -1: [0, 60000],
        0: [100, 20, 10],
        100: [30],
        30: [400, 500],
        60000: [70, 80, 600],
        500: [495, 496, 497]
    }
    

    除了使用正确的连接器外,检查grander并将上次ptree调用的缩进从4增加到5是关键。


    ptree(-1, dct)
    # Out
    ├────0
    │    ├────100
    │    │    └────30
    │    │         ├────400
    │    │         └────500
    │    │              ├────495
    │    │              ├────496
    │    │              └────497
    │    ├────20
    │    └────10
    └────60000
         ├────70
         ├────80
         └────600
    
        2
  •  1
  •   Prune    6 年前

    缩进量是根据节点值的打印图像进行移位的问题,而不是4个空格的常量。这个 math log10 ceil 做这项工作的方法。

    import sys
    import math
    
    
    dct = {
        -1: [0, 60000],
        0: [100, 20, 7],
        100: [30],
        30: [400, 500],
        60000: [70, 80],
        7: [9, 11, 13],
    }
    
    
    def ptree(parent, tree, indent=''):
    
        if parent != -1:
            print(parent)
    
        if parent not in tree:
            return
    
        shift = math.ceil(math.log10(parent)) \
                if parent >= 10 else 1
        indent += ' ' * shift
    
        for child in tree[parent][:-1]:
            print(indent + '|' + '-' * 4, end='')
            ptree(child, tree, indent + '|' + ' ' * 4)
    
        child = tree[parent][-1]
        print(indent + '`' + '-' * 4, end='')
        ptree(child, tree, indent + ' ' * 4)
    
    
    ptree(-1, dct)
    

    输出:

     |----0
     |     |----100
     |     |      `----30
     |     |            |----400
     |     |            `----500
     |     |----20
     |     `----7
     |          |----9
     |          |----11
     |          `----13
     `----60000
              |----70
              `----80