gpt4 book ai didi

Python将字典的平面列表转换为层次结构树

转载 作者:行者123 更新时间:2023-12-04 00:28:10 24 4
gpt4 key购买 nike

我在尝试转换以下列表时遇到了问题:

lst = [
{"id": 0, "job": "CEO", "ManagerID": 0, "name": "John Smith"},
{"id": 1, "job": "Medical Manager", "ManagerID": 0, "name": "Medic 1"},
{"id": 2, "job": "Medical Assist", "ManagerID": 1, "name": "Medic 2"},
{"id": 3, "job": "ICT Manager", "ManagerID": 0, "name": "ICT 1"},
{"id": 4, "job": "ICT Assist", "ManagerID": 3, "name": "ICT 2"},
{"id": 5, "job": "ICT Junior", "ManagerID": 4, "name": "ICT 3"}
]

变成像

这样的格式
output = [
{"id": 0, "job": "CEO", "ManagerID": 0, "name": "John Smith", "children" : [
{ "id":1, "job": "Medical Manager", "name": "Medic 1", "children" : [
{"id": 2, "job": "Medical Assist", "name": "Medic 2"}
]
},
{"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"}
]}
]}
],
}]

是否有一个根节点 (ManagerID = 0) 是否有其他所有分支。

我已尝试修改 another question 中的代码但我无法生成这种所需的格式

我一直使用的代码如下,但这仍然有父节点的重复

classes = [] #everyones id
for item in lst:
name = item['id']
if name not in classes:
classes.append(name)

treenodes = {}
root_node = None

for item in lst: # Create tree nodes
item['children'] = []
name = item['id']
treenodes[name] = item
parent = item['ManagerID']
if parent not in classes: # parent is root node, create
if parent not in treenodes:
node = {}
node['ManagerID'] = 0 #set manager to root
node['children'] = []
node['id'] = parent
root_node = node
treenodes[parent] = node

# Connect parents and children
for item in lst: # Create tree nodes
parent = item['ManagerID']
parent_node = treenodes[parent]
parent_node['children'].append(item)

output = treenodes

非常感谢任何帮助。

最佳答案

这是用于构建层次结构的递归版本。

递归版本

from pprint import pprint


def to_lookup(employees):
employee_lookup = dict()
for employee in employees:
if employee["id"] != employee["ManagerID"]:
manager_id = employee["ManagerID"]
children = employee_lookup.get(manager_id)
if not children:
children = employee_lookup[manager_id] = list()
children.append(employee.copy())
else:
manager = employee.copy()
return manager, employee_lookup


def build_hierarchy(manager, employee_lookup):
employees = employee_lookup.get(manager["id"], list())
for employee in employees:
build_hierarchy(employee, employee_lookup)
if employees:
manager['children'] = employees
return manager


employees = [
{"id": 0, "job": "CEO", "ManagerID": 0, "name": "John Smith"},
{"id": 1, "job": "Medical Manager", "ManagerID": 0, "name": "Medic 1"},
{"id": 2, "job": "Medical Assist", "ManagerID": 1, "name": "Medic 2"},
{"id": 3, "job": "ICT Manager", "ManagerID": 0, "name": "ICT 1"},
{"id": 4, "job": "ICT Assist", "ManagerID": 3, "name": "ICT 2"},
{"id": 5, "job": "ICT Junior", "ManagerID": 4, "name": "ICT 3"}
]

manager, employee_lookup = to_lookup(employees)
hierarchy = build_hierarchy(manager, employee_lookup)
pprint(hierarchy)

输出

{'ManagerID': 0,
'children': [{'ManagerID': 0,
'children': [{'ManagerID': 1,
'id': 2,
'job': 'Medical Assist',
'name': 'Medic 2'}],
'id': 1,
'job': 'Medical Manager',
'name': 'Medic 1'},
{'ManagerID': 0,
'children': [{'ManagerID': 3,
'children': [{'ManagerID': 4,
'id': 5,
'job': 'ICT Junior',
'name': 'ICT 3'}],
'id': 4,
'job': 'ICT Assist',
'name': 'ICT 2'}],
'id': 3,
'job': 'ICT Manager',
'name': 'ICT 1'}],
'id': 0,
'job': 'CEO',
'name': 'John Smith'}

性能测试

hierarchy_size = 2000000

employees = [
{"id": 0, "ManagerID": 0},
]
for idx in range(1, hierarchy_size):
manager_id = random.randint(0, idx - 1)
employees.append({"id": idx, "ManagerID": manager_id})

start = datetime.datetime.now()

manager, employee_lookup = to_lookup(employees)
hierarchy = build_hierarchy(manager, employee_lookup)

print(datetime.datetime.now() - start)

关于Python将字典的平面列表转换为层次结构树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54553328/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com