我在这里扩展我的原始问题:this。
我正在尝试在单个包含列表的字典列表之间合并一些数据。如果“ object”和“ semver”键匹配,则会进行合并。如果匹配相同的值,还将添加到其给定的“部分”中。给定以下数据:
data = [
{
"semver":"1.0.0",
"sections":[
{
"name":"Add",
"messages":[
"add: comment here"
]
}
],
"object":"files.sh"
},
{
"semver":"1.0.0",
"sections":[
{
"name":"Add",
"messages":[
"add: Second comment here"
]
}
],
"object":"files.sh"
},
{
"semver":"1.0.0",
"sections":[
{
"name":"Fix",
"messages":[
"Comment here"
]
}
],
"object":"files.sh"
},
{
"semver":"2.0.0",
"sections":[
{
"name":"Fix",
"messages":[
"2.0.0 Fix Comment here"
]
}
],
"object":"files.sh"
},
{
"semver":"2.0.0",
"sections":[
{
"name":"Add",
"messages":[
"2.0.0 Add Comment here"
]
}
],
"object":"files.sh"
},
{
"semver":"2.0.0",
"sections":[
{
"name":"Add",
"messages":[
"2.0.0 comment for the NewFile"
]
}
],
"object":"NewFile.sh"
},
]
我希望最终实现这一目标
data = [
{
"semver":"1.0.0",
"sections":[
{
"name":"Add",
"messages":[
"add: comment here",
"add: Second comment here"
]
},
{
"name":"Fix",
"messages":[
"Fix: comment here"
]
}
],
"object":"files.sh"
},
{
"semver":"2.0.0",
"sections":[
{
"name":"Add",
"messages":[
"2.0.0 Add comment here",
]
},
{
"name":"Fix",
"messages":[
"2.0.0 Fix Comment here"
]
}
],
"object":"files.sh"
},
{
"semver":"2.0.0",
"sections":[
{
"name":"Add",
"messages":[
"2.0.0 comment for the NewFile"
]
}
],
"object":"NewFile.sh"
},
]
代码块
objects = {} # mapping for object: object_data with sections
sections = defaultdict(list) # mapping for object: all sections
for d in data:
print(d["semver"])
for k, v in list(d.items()):
if v == d["semver"]:
try:
section = d.pop("sections")
sections[d["object"]].extend(section)
objects[d["object"]] = d # populate with object data without sections
except Exception as e:
print(e)
pass
output = []
for object_name, object_data in objects.items():
object_data["sections"] = sections[object_name]
output.append(object_data)
到目前为止,我正在遍历dict
中的每个k,v对,但是无法绕过两个版本之间的匹配并在循环中追加到特定的dict
上。
答案 0 :(得分:1)
应进行2项更改:
objects
和sections
的组合,将object
和semver
中的键更改为。 尝试一下:
import json # just for pretty print, you don't have to use it
from collections import defaultdict
def merge_messages(sections):
d = defaultdict(list)
for m in sections:
d[m["name"]].extend(m["messages"])
return [{"name": k, "messages": v} for k, v in d.items()]
objects = {} # mapping for data with sections for (object, semver) combinations
sections = defaultdict(list) # mapping for sections data for (object, semver) combinations
for d in data:
section = d.pop("sections")
sections[(d["object"], d["semver"])].extend(section) # extends the sections for the object
objects[(d["object"], d["semver"])] = d # # populate with object data without sections
# merge between sections and objects by object key
output = []
for comb, object_data in objects.items():
object_data["sections"] = merge_messages(sections[comb])
output.append(object_data)
print(json.dumps(output, indent=4)) # just for pretty print