我的数据格式如下:
[['Director', 9010],
['Director - Product Manager', 9894],
['Director - Product Manager - Project Manager', 9080],
['Director - Product Manager - Project Manager - Staff', 5090],
['Director - Product Manager - Project Manager - Staff 2', 5087],
['Director - Product Manager - Project Manager 2', 9099],...]
并希望输出看起来像这样:
{
'title': 'Director',
'id': 9010,
'children': [
{
'title': 'Product Manager',
'id': 9894,
'children': [
{
'title': 'Project Manager',
'id': 9080,
'children': [
...
]
},{
'title': 'Project Manager 2',
'id': 9099,
'children': [
...
]
}],
...
]
},
...
]
}
我一直在玩字典,但努力将ID与标题相匹配。任何建议都表示赞赏。
答案 0 :(得分:2)
执行此操作的有效方法是将最外层设为列表而不是字典。当我们遍历标题字符串中的每个标题时,我们在当前列表中查找具有该标题的字典。如果当前列表中不存在标题,那么我们需要创建一个新的字典。如果它确实存在,那么我们将该dict的子列表设为新的当前列表并继续寻找下一个标题。
我还编写了一个递归prune
函数,一旦我们输入了所有数据,就会删除所有空子列表,以防你想要这样做。
import json
lst = [
['Director', 9010],
['Director - Product Manager', 9894],
['Director - Product Manager - Project Manager', 9080],
['Director - Product Manager - Project Manager - Staff', 5090],
['Director - Product Manager - Project Manager - Staff 2', 5087],
['Director - Product Manager - Project Manager 2', 9099],
]
# Search for a matching name in the current list.
# If it doesn't exist, create it.
def insert(lst, name, idnum):
for d in lst:
if d['title'] == name:
break
else:
d = {'title': name, 'id': idnum, 'children': []}
lst.append(d)
return d['children']
# Remove empty child lists
def prune(lst):
for d in lst:
if d['children']:
prune(d['children'])
else:
del d['children']
# Insert the data into the master list
master = []
for names, idnum in lst:
lst = master
for name in [s.strip() for s in names.split(' - ')]:
lst = insert(lst, name, idnum)
prune(master)
# Get the top level dict from the master list
data = master[0]
print(json.dumps(data, indent=4))
<强>输出强>
{
"title": "Director",
"id": 9010,
"children": [
{
"title": "Product Manager",
"id": 9894,
"children": [
{
"title": "Project Manager",
"id": 9080,
"children": [
{
"title": "Staff",
"id": 5090
},
{
"title": "Staff 2",
"id": 5087
}
]
},
{
"title": "Project Manager 2",
"id": 9099
}
]
}
]
}
答案 1 :(得分:0)
以d
作为输入,使用。
由于每个子列表中都有两个元素,因此将迭代变量中的位置和ID保存为p
和id
示例,您正在处理列表['Director - Product Manager - Project Manager - Staff', 5090],
要获取每个位置的标题,您可以将您的位置拆分为-
,并去除前导和尾随空格。例如,
>>> d[3][0]
'Director - Product Manager - Project Manager - Staff'
>>> map(str.strip,d[3][0].split('-'))
['Director', 'Product Manager', 'Project Manager', 'Staff']
输出dict以及前一个Staff
位置被传递给递归搜索方法,并且它获取查找值的所有匹配,即Project Manager
并返回一个列表。获取最后一场比赛。
>>> recursive_search([data,],'Product Manager')[-1]
{'children': [{'children': [{'id': 5090, 'title': 'Staff'}, {'id': 5087, 'title': 'Staff 2'}], 'id': 9080, 'title': 'Project Manager'}, {'id': 9099, 'title': 'Project Manager 2'}], 'id': 9894, 'title': 'Product Manager'}
您需要将新ID添加到上述结果的children
键中!
结合以上所有,
d=[['Director', 9010],['Director - Product Manager', 9894],['Director - Product Manager - Project Manager', 9080],['Director - Product Manager - Project Manager - Staff', 5090],['Director - Product Manager - Project Manager - Staff 2', 5087],['Director - Product Manager - Project Manager 2', 9099],]
from pprint import pprint
def recursive_search(items, key):
found = []
for item in items:
if isinstance(item, list):
found += recursive_search(item, key)
elif isinstance(item, dict):
if key in item.values():
found.append(item)
found += recursive_search(item.values(), key)
return found
data={}
for p,id in d:
desig = map(str.strip,p.split('-'))
if len(desig)>1:
res = recursive_search([data,],desig[-2])[-1]
if res:
res['children']=res.get('children',[])
res['children'].append({'id':id,'title':desig[-1]})
else:
data = {'id':id,'title':p}
pprint.pprint(data)
输出:
{'children': [{'children': [{'children': [{'id': 5090, 'title': 'Staff'},
{'id': 5087,
'title': 'Staff 2'}],
'id': 9080,
'title': 'Project Manager'},
{'id': 9099, 'title': 'Project Manager 2'}],
'id': 9894,
'title': 'Product Manager'}],
'id': 9010,
'title': 'Director'}
参考:这里使用的recursive_search函数是通过提到here
的字典进行搜索的略微修改版本