假设我们有如下列表
[
{
"一级": "数码产品",
"二级": "手机",
"三级": "苹果",
"四级": "iPhone11",
"编码": "001"
},
{
"一级": "数码产品",
"二级": "电脑",
"三级": "苹果",
"四级": "MacBook",
"编码": "002"
},
{
"一级": "数码产品",
"二级": "手机",
"三级": "苹果",
"四级": "iPhone12",
"编码": "003"
},
{
"一级": "数码产品",
"二级": "耳机",
"三级": "苹果",
"四级": "AirPods",
"编码": "004"
},
{
"一级": "数码产品",
"二级": "手机",
"三级": "三星",
"四级": "Galaxy",
"编码": "005"
}
]
我们希望将其变为如下树形结构的字典
{
"数码产品": {
"手机": {
"苹果": {
"iPhone11": {
"编码": "001"
},
"iPhone12": {
"编码": "003"
}
},
"三星": {
"Galaxy": {
"编码": "005"
}
}
},
"电脑": {
"苹果": {
"MacBook": {
"编码": "002"
}
}
},
"耳机": {
"苹果": {
"AirPods": {
"编码": "004"
}
}
}
}
}
test = [
{"一级": "数码产品", "二级": "手机", "三级": "苹果", "四级": "iPhone", "编码": "001"},
{"一级": "数码产品", "二级": "电脑", "三级": "苹果", "四级": "MacBook", "编码": "002"},
{"一级": "数码产品", "二级": "耳机", "三级": "苹果", "四级": "AirPods", "编码": "003"},
{"一级": "数码产品", "二级": "手机", "三级": "三星", "四级": "Galaxy", "编码": "004"}
]
for name_0 in set(d['一级'] for d in test):
dic[name_0] = {}
for name_1 in set(d['二级'] for d in test if d['一级'] == name_0):
dic[name_0][name_1] = {}
for name_2 in set(d['三级'] for d in test if d['一级'] == name_0 and d['二级'] == name_1):
dic[name_0][name_1][name_2] = {}
for name_3 in set(d['四级'] for d in test if d['一级'] == name_0 and d['二级'] == name_1 and d['三级'] == name_2):
dic[name_0][name_1][name_2][name_3] = {}
for item in test:
dic[item['一级']][item['二级']][item['三级']][item['四级']]['编码'] = item['编码']
但是这种方式单从代码上看就非常繁琐,而且不灵活,应该还会有更好的办法
我们发现以下代码仅是为了创建分支节点
for name_0 in set(d['一级'] for d in test):
dic[name_0] = {}
for name_1 in set(d['二级'] for d in test if d['一级'] == name_0):
dic[name_0][name_1] = {}
for name_2 in set(d['三级'] for d in test if d['一级'] == name_0 and d['二级'] == name_1):
dic[name_0][name_1][name_2] = {}
for name_3 in set(d['四级'] for d in test if d['一级'] == name_0 and d['二级'] == name_1 and d['三级'] == name_2):
dic[name_0][name_1][name_2][name_3] = {}
我们可以利用defaultdict,在键不存在的时候自动创建,从而将上面的代码省略掉
import json
from collections import defaultdict
test = [
{"一级": "数码产品", "二级": "手机", "三级": "苹果", "四级": "iPhone", "编码": "001"},
{"一级": "数码产品", "二级": "电脑", "三级": "苹果", "四级": "MacBook", "编码": "002"},
{"一级": "数码产品", "二级": "耳机", "三级": "苹果", "四级": "AirPods", "编码": "003"},
{"一级": "数码产品", "二级": "手机", "三级": "三星", "四级": "Galaxy", "编码": "004"}
]
dic = defaultdict(lambda: defaultdict(lambda: defaultdict(lambda: defaultdict(dict))))
for item in test:
dic[item['一级']][item['二级']][item['三级']][item['四级']]['编码'] = item['编码']
# 转为字典
json.loads(json.dumps(dic))
注意:
- 转字典时,dict()方式仅能转换根节点,子节点则依然为defaultdict,故需要使用json;
- 上面定义的dic最大能满足层数为5的树,如果层数大于5则需要在定义dic的时候再多嵌套若干层defaultdict(lambda: defaultdict(dict))
参考:
https://howchoo.com/python/nested-defaultdict-python
https://stackoverflow.com/a/32303615/7151777