如何将其转换为递归函数?

时间:2018-04-27 21:29:51

标签: python recursion graph

我尝试根据通过名为reports_to的属性引用自身的模型创建组织结构图。我不知道组织结构图下面会有多少级别,所以我觉得递归函数是有意义的。这里有一些代码可以使用:

top_level = Person.objects.filter(reports_to=None)
org_chart = {}
for person in top_level:
    org_chart[person] = {}
    if person.has_direct_reports():
        direct_reports = Person.objects.filter(reports_to=person)
        for p in direct_reports:
            org_chart[person][p] = {}
            if p.has_direct_reports():
                direct_reports_2 = Person.objects.filter(reports_to=p)
                for q in direct_reports_2:
                    org_chart[person][p][q] = {}
                        # ... and so on

这导致shell输出如下:

>>> pp.pprint(org_chart)
{   <Person: Joe Boss>: {   <Person: John Doe>: {   <Person: John Doe Jr>: {   },
                                                          <Person: Jane Doe>: {   }}},
    <Person: Partner Mary>: {}}

哪个是对的。显示清洁剂:

Joe Boss
- John Doe
-- John Doe Jr
-- Jane Doe
Partner Mary

我一直试图将此代码转换为递归函数,但我的大脑却没有解决问题。感谢您解决此问题的任何建议或帮助!

编辑。这是我尝试工作的代码,但我在这个过程中摔倒了自己:

def direct_reports_r(person):
    if person.has_direct_reports():
        direct_reports = Person.objects.filter(reports_to=person)
        for person in direct_reports:
            org_chart[person] = {}
            if person.has_direct_reports():
                direct_reports = Person.objects.filter(reports_to=person)
                org_chart[person] = direct_reports_r(person)
            else:
                return person
    else:
        return False

top_level = Person.objects.filter(reports_to=None)
org_chart = {}
for person in top_level:
    org_chart[person] = {}
    # recursion
    org_chart[person][direct_reports_r(person)] = {}

2 个答案:

答案 0 :(得分:2)

我希望这段代码有效。

def foo(person, tmp_root):
    tmp_root[person] = {}
    if person.has_direct_reports():
        direct_reports = Person.objects.filter(reports_to=person)
        for p in direct_reports:
            foo(p, tmp_root[person])

org_chart = {}
top_level = Person.objects.filter(reports_to=None)
for person in top_level:
    foo(person, org_chart)

答案 1 :(得分:1)

传递列表是可变的,以及字典,因此当您将其传递给参数时,它是通过引用来实现的。以下是您可以使用的示例,以达到理想的效果。

top_level = Person.objects.filter(reports_to=None)
org_chart = {}

def init_org_chart(reports, arg):
    for person in reports:
        arg[person] = {}
        if person.has_direct_reports():
            direct_reports = Person.objects.filter(reports_to=person)
            init_org_chart(direct_reports, arg[person])

init_org_chart(top_level, org_chart)