我试图创建一个基于模型的组织结构图,该模型通过一个名为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)] = {}

最佳答案

传递的列表和字典都是可变的,所以当您将其传递到参数时,它是通过引用传递的。下面是一个例子,你可以用它来达到预期的效果。

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)

10-05 18:38