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