递归函数从{string:list}对的平面字典创建层次结构

时间:2019-07-12 15:02:53

标签: python json recursion

我需要一个函数来获取列表的字典并生成层次结构的字典。我一直都有根密钥,因此可以使用根密钥作为参数来调用该函数。没有循环引用。如果某项没有子项,则应返回“ DATA”。

我快到了,但是结果是那些带有字典作为子节点的键最终又增加了一个子代。

flat = {'g': ['h', 'i', 'j'],
        'b': ['e', 'f', 'g', 'm'],
        'a': ['b', 'c', 'd'],
        'm': ['n', 'o', 'p']}


what_the_result_should_be = {'a': {'c': 'DATA','d': 'DATA', 'b': {'m':{'n': 'DATA', 'o': 'DATA', 'p': 'DATA'}, 'e': 'DATA','f': 'DATA','g':{'h': 'DATA', 'i': 'DATA', 'j': 'DATA'}}}}

def walk(d, node):
    if d.get(node, None):
        return {node : {child : walk(d, child) for child in d[node]}}
    else:
        return 'DATA'

what_my_attempt_produces = walk(flat, 'a')

2 个答案:

答案 0 :(得分:2)

您可以使用递归:

flat = {'g': ['h', 'i', 'j'], 'b': ['e', 'f', 'g', 'm'], 'a': ['b', 'c', 'd'], 'm': ['n', 'o', 'p']}
def create(a):
   r = {}
   for i in flat[a]:
     if i not in flat:
       r[i] = 'DATA'
     else:
       r.update(create(i))
   return {a:r}

result = create('a')
print(what_the_result_should_be == result)

输出:

True

输出:

{'a': {'b': {'e': 'DATA', 'f': 'DATA', 'g': {'h': 'DATA', 'i': 'DATA', 'j': 'DATA'}, 'm': {'n': 'DATA', 'o': 'DATA', 'p': 'DATA'}}, 'c': 'DATA', 'd': 'DATA'}}

答案 1 :(得分:1)

我将分两步执行此操作。首先,为每个键构建“虚拟”数据结构:

dummy = {elem:({} if elem in flat.keys() else 'DATA')
            for v in flat.values() 
            for elem in v}

然后,使用来自"dummy"的引用来构建适当的层次结构:

result = {}
for key, value in flat.items():
    head = dummy.get(key, {})
    for elem in value:
        head[elem] = dummy[elem]
    if key not in dummy:
        result[key] = head

这将产生:

{'a': {'b': {'e': 'DATA',
             'f': 'DATA',
             'g': {'h': 'DATA', 'i': 'DATA', 'j': 'DATA'},
             'm': {'n': 'DATA', 'o': 'DATA', 'p': 'DATA'}},
       'c': 'DATA',
       'd': 'DATA'}}