如何将分层列表排序为字典的树/pyrimid 模型?

Posted

技术标签:

【中文标题】如何将分层列表排序为字典的树/pyrimid 模型?【英文标题】:How would I sort a hierarchical list into a tree/pyrimid model of dicts? 【发布时间】:2014-09-15 19:26:38 【问题描述】:

我正在尝试生成用于在 Qt 中创建树模型的 dicts 层次结构。

数据在一个列表中,每个条目是 [Next Sibling, Previous Sibling, First_Child, Parent] 并且列表中元素的索引是描述的轮廓的名称/索引层次结构条目。

例如,如果我要从第 4.RETR_TREE here 部分输入层次结构

hierarchy = 
    array([[[ 7, -1,  1, -1],
            [-1, -1,  2,  0],
            [-1, -1,  3,  1],
            [-1, -1,  4,  2],
            [-1, -1,  5,  3],
            [ 6, -1, -1,  4],
            [-1,  5, -1,  4],
            [ 8,  0, -1, -1],
            [-1,  7, -1, -1]]])

我想得到这个输出:

0:1:2:3:4:5:,6:,
7:,
8:

我希望这样做是为了在 Qt 中构建一个树模型,以便我可以轻松查看哪些轮廓包含哪些其他轮廓。如果您对如何将层次结构数据转换为 Qt 树模型有更好的了解,也将不胜感激。

提前致谢!

【问题讨论】:

【参考方案1】:

类似于@uselpa 我想出了一个解决方案,它不对具有相同父节点的节点进行排序,因为 Python 字典没有固定顺序:

import numpy as np
H = np.array(
    [[ 7, -1,  1, -1],
     [-1, -1,  2,  0],
     [-1, -1,  3,  1],
     [-1, -1,  4,  2],
     [-1, -1,  5,  3],
     [ 6, -1, -1,  4],
     [-1,  5, -1,  4],
     [ 8,  0, -1, -1],
     [-1,  7, -1, -1]])

def T(i):
    children = [(h, j) for j, h in enumerate(H) if h[3] == i]
    children.sort(key = lambda h: h[0][1])
    return c[1]: T(c[1]) for c in children

print T(-1)

输出:

0: 1: 2: 3: 4: 5: , 6: , 8: , 7: 

因此,您可以跳过对子项进行排序并最终得到以下紧凑代码:

T = lambda i: j: T(j) for j, h in enumerate(H) if h[3] == i
print T(-1)

【讨论】:

哇!我看到这适用于简单的列表列表,不需要 numpy。这是我们这些没有 dict 理解的人的版本:T = lambda i: dict((j, T(j)) for j, h in enumerate(H) if h[3] == i); print T(-1)【参考方案2】:

我不熟悉 Qt、numpy 或 opencv,所以我可能在这里遗漏了一些东西,但无论如何我都会尝试一下。

以下算法根据要求创建字典:

def make_hdict(hier):
    def recur(parent):
        res = 
        for i,n in enumerate(hier):
            if n[3] == parent:
                res[i] = recur(i)
        return res
    return recur(-1)

测试:

hierarchy = [[ 7, -1,  1, -1], #0
             [-1, -1,  2,  0], #1
             [-1, -1,  3,  1], #2
             [-1, -1,  4,  2], #3
             [-1, -1,  5,  3], #4
             [ 6, -1, -1,  4], #5
             [-1,  5, -1,  4], #6
             [ 8,  0, -1, -1], #7
             [-1,  7, -1, -1]] #8    
print(make_hdict(hierarchy))
=> 0: 1: 2: 3: 4: 5: , 6: , 8: , 7: 

如您所见,此时我只使用最后一个字段(“父级”)。 特别是,

    我没有使用“下一个兄弟”和“上一个兄弟”,因为字典是无序的 我没有使用“第一个孩子”,因为它是多余的信息。

这是你想要的吗?

【讨论】:

以上是关于如何将分层列表排序为字典的树/pyrimid 模型?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用字典列表创建分层数据框

将分层平面数据(带 ParentID)转换为带缩进级别的排序平面列表的算法

如何将字典列表转换为 JSON

如何根据字典中值的大小, 对字典中的项排序

python 将列表排序并将其排序为多个部分的函数,或基于数字的列表字典。

列表中嵌套字典,根据字典的值排序