1

I need a function to take this dictionary of lists and produce a hierarchical dictionary. I always have the root key so the function can be called with the root key as an argument. There are no circular references. If an item has no children it should return 'DATA'.

I am almost there but in my result those keys that have a dictionary as child node end up added a second time as a child to itself.

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 Answers 2

2

You can use recursion:

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)

Output:

True

Output:

{'a': {'b': {'e': 'DATA', 'f': 'DATA', 'g': {'h': 'DATA', 'i': 'DATA', 'j': 'DATA'}, 'm': {'n': 'DATA', 'o': 'DATA', 'p': 'DATA'}}, 'c': 'DATA', 'd': 'DATA'}}
Sign up to request clarification or add additional context in comments.

2 Comments

This produces the some double-child result that I have. The '==' doesn't do a deep comparison here, thus the True.
@delica Glad to help!
1

I would do this in two steps. First, build "dummy" data structures for each of your keys:

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

Then, construct a proper hierarchy using references from "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

This yields:

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

2 Comments

This doesn't run even after I add items() to 'for key, value in flat'
Ah, it was because a wasn't in any of the values. I used the get() method instead to account for that, sorry

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.