将扁平数据转换为列表字典树
在我的项目中,我需要列出所有产品,并将它们以嵌套的JSON格式发送到我的应用程序。我已经写了代码来实现这个功能,但我不太明白我的逻辑哪里出错了。以下是我的代码。
我手头的数据是一些简单的字段,比如 type
、category
、sub
、name
、price
等等。
因为 Type、Cat、Sub 是放在一个字符串里的,所以我用 re.search
来解析它们,结果存储在 parse
里。
在我的 Python main
函数中,我获取所有记录,然后在 for each row in rows
循环中,我调用:
product_list = add_on_tree(parse, product_list, p_dict, 1)
这里的 product_list 一开始是 []
,p_dict 是一个字典,像这样:{name:'', price:'',... 等等}
def add_on_tree(parse, plist, pdict, i):
if parse.group(i):
listCheck = ""
"""
empty ==>> plist is empty
match ==>> plist[i].type = parse.group(i)
nomatch ==>> plist[i].type != parse.group(i)
"""
if plist==[]:
listCheck = "empty"
else:
listCheck = "nomatch"
for l in plist:
if l["type"]==parse.group(i):
listCheck = "match"
if listCheck in ["empty", "nomatch"]:
newdict = {}
newdict["type"] = parse.group(i)
newdict["sub"] = []
newdict["leaves"] = []
try:
if parse.group(i+1):
sublist = add_on_tree(parse, [], pdict, i+1 )
newdict["sub"] = sublist
plist.append(newdict)
return plist
except:
newdict["leaves"].append(pdict)
plist.append(newdict)
return plist
else:
for p in plist:
if p["type"]==parse.group(i):
try:
if parse.group(i+1):
sublist = add_on_tree(parse, p["sub"], pdict, i+1)
p["sub"] = sublist
return plist
except:
p["leaves"].append(pdict)
return plist
else:
p["sub"] = ["Error Somewhere", p["type"]]
return plist
需要的树形结构
[
{
type : 'car entertainment',
sub : [
{
type : 'Head Unit',
sub : [
{
type : 'USB',
sub : [],
products : [
{
name : '',
url : '',
price: ''
}
]
}
],
products : []
},
{},
{}
],
products : []
},
{
type : 'home entertainment',
sub : [
{
type : 'Audio',
sub : [],
products : [
{
name:,
url:,
type:
},
{
name:,
url:,
type:
}
]
},
{},
{}
],
products : []
}
]
我得到的结果:
{
"products": [
{
"leaves": [],
"sub": [
"Error Somewhere",
"Car Entertainment"
],
"type": "Car Entertainment"
},
{
"leaves": [],
"sub": [
{
"leaves": [],
"sub": [
{
"leaves": [
{
"desc": "",
"image": "",
"name": "",
"price": 25000.0,
"url": ""
}
],
"sub": [],
"type": "Smartest"
}
],
"type": "Smart"
}
],
"type": "Home Entertainment"
}
]
}
在 flask
中,我使用 jsonify(products=product_list)
,这表示最外层的字典 products
。
附加信息
- 我使用的是
mysql
数据库,里面只有四条记录。 - 当我使用
pdb
调试时,我发现当出现 'error somewhere' 的时候,打印 p["type"] 返回的是 p['type']。 如果我把
product_list = add_on_tree(parse, product_list, p_dict, 1)
改成
product_list = add_on_tree(parse, [], p_dict, 1)
最后一行就能正确渲染。这让我觉得我的逻辑在列表为空的时候是没问题的,但在需要插入到已有结构时就出错了。
任何帮助都非常感谢。提前谢谢你们!
更新 - 解决方案
正如 @matt 指出的那样,错误出在:
else:
p["sub"] = ["Error Somewhere", p["type"]]
return plist
以下的修改解决了这个错误:
else:
return plist
PS - 我后来把嵌套结构替换成了简单数据。嵌套(处理)应该留给最终的应用程序来做。否则会带来更多麻烦,而不是解决问题。
1 个回答
1
你的函数有点复杂,不过我觉得我看到了直接的问题:
else:
p["sub"] = ["Error Somewhere", p["type"]]
return plist
如果列表中的第一个项目和你要找的类型不匹配,你就会出错。其实你应该是在遍历整个列表后,如果没有找到你想要的类型再出错。
试着把错误检查放在循环之后。