我如何将其变成递归功能



我正在尝试基于模型创建一个由称为 reports_to引用自身的模型。我不知道Org图表的层次有多少层次,因此我觉得递归功能很有意义。这是目前有效的一些代码:

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

这会导致这样的外壳输出:

>>> 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)] = {}

我希望此代码有效。

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)

传递的列表是可变的,并且词典是可变的,因此当您将其传递到一个参数中时,它是参考。这是您可以使用的示例来实现所需的结果。

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)

最新更新