Python创建树状图的库,基于嵌套的Python对象(字典)

2024-05-21 04:18:23 发布

您现在位置:Python中文网/ 问答频道 /正文

是否有人知道有任何Python库允许您简单快速地向它提供嵌套到任意级别的对象,例如沿着this gist中找到的内容行的dict树,并且它可以吐出一个可用的树图文件?

在这里,简单是关键,因为我必须能够和那些没有技术头脑的人一起工作。

我所说的“图树”是指如下所示的东西,在这里我可以为它提供一个嵌套的值字典,然后它将创建树结构:


(来源:rubyforge.org


Tags: 文件对象内容字典树图this级别技术
3条回答

我不确定这是不是你想的,但这是第一件想到的事。

blockdiag主要用作类似于Graphviz(存在Python接口)的独立文件处理器。它接受一个文本文件作为输入,使用简单的直接语法,并生成图像作为输出。

您应该能够编写一个简单的填充程序来输出递归dict结构,该结构格式化为独立blockdiag脚本的输入,或者导入blockdiag包的必要内部并直接驱动输出。

如果这听起来很有希望的话,我会看看是否能写出一些示例代码。

编辑示例代码:

def print_blockdiag(tree, parent=None):
    if not parent: print('blockdiag { orientation = portrait')
    for key in tree:
        if parent: print('   {} -> {};'.format(parent, key))
        print_blockdiag(tree[key], key)
    if not parent: print('}')

这将输出一个blockdiag可以读取的文件。

我在寻找一个类似的问题:用嵌套的dict打印dict的密钥,其中的密钥结构是非常周期性的。 因此,我编写了一个递归函数,它打印每个dict和嵌套dict的键,但是对于一个单分支

希望下面的代码片段可以帮助其他人:

from itertools import zip_longest

def dictPrintKeysTopBranch(dic):
    #track recursive depth
    depth=dictPrintKeysTopBranch.data.get('depth',-1)+1;
    dictPrintKeysTopBranch.data['depth']=depth;

    #accumalte keys from nested dicts
    if type(dic) is type(dict()):
        listKeys=sorted(list(dic.keys()));

        #save keys of current depth
        dictPrintKeysTopBranch.data['listKeysDepth{}'.format(depth)]=listKeys;

        #repeat for top branch
        dictPrintKeysTopBranch(dic[listKeys[0]]);

    #print accumalated list of keys
    else: 
        #pad lists 
        lists=[];
        maxlen=[];
        for d in range(depth):
            l=dictPrintKeysTopBranch.data['listKeysDepth{}'.format(d)];
            lists.append(l);

            lens = [len(s) for s in l];
            maxlen.append(max(lens)+1);

        i=-1;
        for zipped in zip_longest(*lists, fillvalue=' '):
            i=i+1;
            #print(x)
            row = '';
            j=-1;
            for z in zipped:
                j=j+1;
                if i==0:
                    row = row+ ((' {: <'+str(maxlen[j])+'} -->\\').format(z));
                else :
                    row = row+ ((' {: <'+str(maxlen[j])+'}    |').format(z));
            print(row.strip('\\|->'));

    dictPrintKeysTopBranch.data={};
dictPrintKeysTopBranch.data={};

这里有一个例子:

mydict = { 'topLv':{'secLv':{'thirdLv':{'item1':42,'item2':'foo'}}}, 
           'topLvItem':[1,2,3], 
           'topLvOther':{'notPrinted':':('}
         }
dictPrintKeysTopBranch(mydict)

输出:

topLv       -->\ secLv  -->\ thirdLv  -->\ item1  
topLvItem      |           |             | item2     
topLvOther     |           |             |         

因此,我推荐并用于我的代码片段的库是一个python库,但它是一个python友好的库,我的意思是使用这个库的代码可以插入到python模块中处理数据,并且这个foreign代码将连接到两端的现有python代码,即,输入和输出,我怀疑,虽然我当然不知道,这就是“python库”标准的全部含义。因此,如果您正在编写一个web应用程序,此代码将是客户端代码。换句话说,这个库不是python,而是与python一起工作的。

  1. 它的输入是(几乎)原始的python dict,更具体地说,json.load(a_python_dict)返回一个json数组或对象,这个javascript库当然可以识别这种格式;并且

  2. 输出格式是HTML或SVG,而不是某些 语言特定格式

您可以使用d3.js。它有一个class专门用于呈现树:

var tree = d3.layout.tree().size([h, w]);

d3源中的example文件夹中还有两个树(工作代码)示例,您可以从上面提供的链接中克隆/下载它们。

因为d3是一个javascript库,它的本地数据格式是JSON

基本结构是一个嵌套字典,每个字典用两个值表示一个节点,节点的名称及其子节点(存储在数组中),分别键入name schildren

{"name": "a_root_node", "children": ["B", "C"]}

当然,在python字典和JSON之间转换也很简单:

>>> d = {"name": 'A', "children": ['B', 'C']}
>>> import json as JSON
>>> dj = JSON.dumps(d)
>>> dj
    '{"name": "A", "children": ["B", "C"]}'

下面是一个pythondictionary表示更大的树(十几个节点),我将其转换为json,然后在d3中呈现,如下图所示:

tree = {'name': 'root', 'children': [{'name': 'node 2', 'children': 
       [{'name': 'node 4', 'children': [{'name': 'node 10', 'size': 7500}, 
       {'name': 'node 11', 'size': 12000}]}, {'name': 'node 5', 'children': 
       [{'name': 'node 12', 'children': [{'name': 'node 16', 'size': 10000}, 
       {'name': 'node 17', 'size': 12000}]}, {'name': 'node 13', 'size': 5000}]}]}, 
       {'name': 'node 3', 'children': [{'name': 'node 6', 'children': 
       [{'name': 'node 14', 'size': 8000}, {'name': 'node 15', 'size': 9000}]}, 
       {'name': 'node 7', 'children': [{'name': 'node 8', 'size': 10000}, 
       {'name': 'node 9', 'size': 12000}]}]}]}

tree represented as python dictionary rendered in d3:

注意:d3在浏览器中呈现;上面的图像只是我的浏览器窗口的屏幕快照。

相关问题 更多 >