Patthebug
Patthebug

Reputation: 4787

Recursion in dict

I have a nested dict which looks like this:

enter image description here

There are multiple nestings within the key children. I would like to capture the key branch whenever the key children is present. Because there are multiple children, I would like to do this for each child. Ofcourse, each child can also have further children. This nesting can go upto 7 levels.

To achieve this, I could either write a boneheaded 7-for loop method or use recursion. So I gave recursion a shot and came up with the following code:

def GatherConcepts(header):
    if 'children' in header.keys():
        if len(header['children']) > 0:
            if 'branch' in header.keys():
                concepts.append(header['handle'])
                if 'children' in header.keys():
                    for j in range(0, len(header['children'])):
                        GatherConcepts(header['children'][j])
            else:
                for i in range(0,len(header['children'])):
                    GatherConcepts(header['children'][i])

The problem with this code is that it gives me only 2 levels (because I'm calling the function itself 2 times, thereby not using recursion properly), not 7.

How can I improve this to get all the levels?

Any pointers would be highly appreciated.

Upvotes: 2

Views: 203

Answers (2)

Barmar
Barmar

Reputation: 781130

You have some unnecessary redundancies. If I understand you correctly, you need to add the handles to the list separately from the recursion, because you want to test branch in the parent.

def GatherConcepts(header):
    if 'children' in header and 'branch' in header:
        for child in header['children']:
            concepts.append(child['handle'])
            GatherConcepts(child)

You don't need to test the length of header['children'] -- if it's zero then the loop will just not do anything.

Upvotes: 1

sehrob
sehrob

Reputation: 1044

In order to get recursion correctly, you can use this simple template for it:

def recursive(variable):
    if something:
        # base step
        return somethingelse
    else:
        # recursive step
        return recursive(somethingelse)

In your case, you can try something like this:

def gather_concepts(header):
    # recursive step
    if 'branch' in header and 'handle' in header:
        concepts.append(header['handle'])
    if 'children' in header:
        for child in header['children']:
            return gather_concepts(child)
    # base step
    else:
        return

You should tweak this code under your needs though, because I haven't tested it myself.

Upvotes: 0

Related Questions