在python中从嵌套字典创建分层树

时间:2017-11-26 14:19:32

标签: python dictionary tree rdf taxonomy

我有一个包含大约600,000条维基数据分类记录的大型RDF文件。从这个文件中,我只对subclassOf关系(谓词)感兴趣,因此,我忽略了只保留“subclassOf”语句的所有其他语句。声明如下: a is a subclassOf bb is a subclassOf c 例如,cb的父级,而b的父级是a的父级。任何父母都可以有很多孩子。我想使用这个分类法构建分层树。  我检查了这个帖子,它几乎解决了我的问题。 Recursively creating a tree hierarchy without using class/object 然而,有了这个,我在字典中得到树,我想转换成树数据结构。以下是我的尝试:

data = [['a','x'], ['b','x'], ['c','x'], ['x','y'], ['t','y'], ['y','p'], ['p','q']]

roots = set()
mapping = {}
for child,parent in data:        
    childitem = mapping.get(child,None)
    if childitem is None:
        childitem =  {}
        mapping[child] = childitem
    else:
        roots.discard(child)
    parentitem = mapping.get(parent,None)
    if parentitem is None:
        mapping[parent] = {child:childitem}
        roots.add(parent)
    else:
        parentitem[child] = childitem

for root in roots:
    print(mapping[root])

tree = { id : mapping[id] for id in roots }
print(tree)

树的输出如下所示:

{'q': {'p': {'y': {'t': {}, 'x': {'c': {}, 'b': {}, 'a': {}}}}}}

我想将此词典转换为树。所以例如当我说print(mapping ['y'])时,它应该给我Node y ie

q
├── p
    └── y

目前,如果我说映射['y'],它会给我以y为根的子树。我认为这有一些简单的解决方案,但我无法理解它。我也找到了这个链接https://gist.github.com/hrldcpr/2012250来将字典转换为树,但不知道如何在我的情况下使用它。另外,如果有人知道从我上面给出的RDF数据直接构建树,那么它将是非常受欢迎的。可能python的anytree API将解决我的问题。

1 个答案:

答案 0 :(得分:1)

如果你不介意额外的O(N)空间,你可以保留一个parents字典,为每个关键孩子存储父值。并在主for循环中填充它。

现在找到所有祖先非常容易。递归查找父级的所有祖先,并将当前节点附加到该结果。

data = [['a','x'], ['b','x'], ['c','x'], ['x','y'], ['t','y'], ['y','p'], ['p','q']]
parents = {} #to store parents
roots = set()
mapping = {}
for child,parent in data:
    parents[child] = parent #populate parents
    childitem = mapping.get(child,None)
    ................................

def ancestors(node): #the ancestor-finding function
    if not node: return []
    return ancestors(parents.get(node))+[node]

def first_k_ancestor(node,k=5):
    ances = ancestors(node)
    ances.reverse()
    return ances[:k]


print(ancestors('a'))

打印:

['q', 'p', 'y']