Ваш код на самом деле работает, но вам нужно принять запись treenodes[0]
(генеральный директор).Остальные пары ключ-значение в treenodes
предназначены только для бухгалтерии, чтобы легко найти данного менеджера для данной записи сотрудника.
Если вы не можете рассчитывать на 0
, являющийся идентификаторомкорневой узел, тогда вы можете использовать тот факт, что генеральный директор помечен как управляющий собой;корневой узел - это тот, где идентификатор менеджера указывает на их собственный идентификатор.Более распространенный сценарий состоит в том, что корневые узлы просто не имеют родительского идентификатора.
Вы также добавили генерального директора в свой собственный список children
(идентификатор менеджера для генерального директора является их собственным идентификатором), поэтому у вас естьрекурсивная ссылка в вашем дереве.
Код, который вы нашли, не самый ясный и не самый эффективный.Я построил бы словарь из id
для скопированного объекта (так что ваши исходные словари lst
не изменились), затем перебрал бы эту структуру и добавил бы записи к их записи идентификатора менеджера.Я использую правило «ссылки на корневые узлы» (таким образом, идентификатор менеджера равен их собственному идентификатору):
employees = {}
managers = set()
root_id = None
for emp in lst:
id, mid = emp['id'], emp['ManagerID']
# create a copy of emp, and add a "children" list
employees[id] = {**emp, 'children': []}
managers.add(mid)
if id == mid:
# the root of the tree references itself as the manager
root_id = id
# add empty manager entries for missing manager IDs, reporting to root ID.
for id in managers - employees.keys():
employees[id] = {
'id': id, 'ManagerID': root_id, 'children': [],
'job': None, 'name': None
}
for id, emp in employees.items():
manager = employees[emp.pop('ManagerID')]
if id != root_id: # don't add the root to anything
manager['children'].append(emp)
output = employees[root_id]
Приведенное выше описание использует набор для отслеживания того, какие идентификаторы менеджера были замечены, поэтому вы можететривиально добавьте отсутствующие записи менеджера (в данном случае сообщая генеральному директору).
Для вашего ввода, который выдает:
{'id': 0, 'job': 'CEO', 'name': 'John Smith', 'children':
[{'id': 1, 'job': 'Medical Manager', 'name': 'Medic 1', 'children':
[{'id': 2, 'job': 'Medical Assist', 'name': 'Medic 2', 'children': []}],
},
{'id': 3, 'job': 'ICT Manager', 'name': 'ICT 1', 'children':
[{'id': 4, 'job': 'ICT Assist', 'name': 'ICT 2', 'children':
[{'id': 5, 'job': 'ICT Junior', 'name': 'ICT 3', 'children': []}]
}]
}]
}