0

Given this dictionary of parent-children relations,

{
    2: [8, 7],
    8: [9, 10],
    10: [11],
    15: [16, 17],
}

I'd like to get the list of all children, grandchildren, great-grandchildren, etc. -- e.g. given a parent with an ID 2 I want to get the following list: [8, 7, 9, 10, 11]. The number of nesting levels can be infinitely long. Cycles are not possible.

So far I was able to achieve this function but I don't know how to return from it:

links = {
    2: [8, 7],
    8: [9, 10],
    10: [11],
    15: [16, 17],
}

def get_nested_children(parent_uid, acc = []):
    if parent_uid in links:
        acc = acc + links[parent_uid]
        print("[in loop]", acc)

        for child_uid in links[parent_uid]:
            get_nested_children(child_uid, acc)
    else:
        return acc

print(get_nested_children(2))

Which outputs:

[in loop] [8, 7]
[in loop] [8, 7, 9, 10]
[in loop] [8, 7, 9, 10, 11]
None
  • 1
    You say you want `children and grandchildren` but also say the nesting can be infinite. Does this mean you also want great-grandchildren, great-great-grandchildren, etc.? Also, are cycles possible? – Mark Nov 16 '22 at 19:40
  • @Mark Yes, all levels of nesting, I did not know how to formulate it better. Cycles are not possible. –  Nov 16 '22 at 20:05
  • Also, is the order important? Typically, recursive traversal will produce depth-first results like `[8, 9, 10, 11, 7]`. – Mark Nov 16 '22 at 20:10
  • I don't think it is. –  Nov 16 '22 at 20:13

1 Answers1

0

Since cycles aren't possible and the order is not important, the easiest way to do this is with a generator function. Just yield the children and yield from the results of recursion. This will give you a depth first result:

links = {
    2: [8, 7],
    8: [9, 10],
    10: [11],
    15: [16, 17],
}

def get_nested_children(parent_uid):
        for child_uid in links.get(parent_uid, []):
            yield child_uid
            yield from get_nested_children(child_uid)


list(get_nested_children(2))
# [8, 9, 10, 11, 7]

If you want a traditional function you can just append each child, then extend the results of recursion onto a local list, which you can return:

def get_nested_children(parent_uid):
        res = []
        for child_uid in links.get(parent_uid, []):
            res.append(child_uid)
            res.extend(get_nested_children(child_uid))
        return res


get_nested_children(2)
# [8, 9, 10, 11, 7]
Mark
  • 90,562
  • 7
  • 108
  • 148