我正在尝试使用python将两个JSON文件合并为一个JSON。
文件1:
{
"key1": "protocol1",
"key2": [
{
"name": "user.name",
"value": "user@EXAMPLE123.COM"
},
{
"name": "user.shortname",
"value": "user"
},
{
"name": "proxyuser.hosts",
"value": "*"
},
{
"name": "kb.groups",
"value": "hadoop,users,localusers"
},
{
"name": "proxy.groups",
"value": "group1, group2, group3"
},
{
"name": "internal.user.groups",
"value": "group1, group2"
}
]
}
文件2:
{
"key1": "protocol1",
"key2": [
{
"name": "user.name",
"value": "user@EXAMPLE456.COM"
},
{
"name": "user.shortname",
"value": "user"
},
{
"name": "proxyuser.hosts",
"value": "*"
},
{
"name": "kb.groups",
"value": ""
},
{
"name": "proxy.groups",
"value": "group3, group4, group5"
},
{
"name": "internal.groups",
"value": "none"
}
]
}
最终预期结果:
{
"key1": "protocol1",
"key2": [
{
"name": "user.name",
"value": "user@EXAMPLE123.COM, user@EXAMPLE456.COM"
},
{
"name": "user.shortname",
"value": "user"
},
{
"name": "proxyuser.hosts",
"value": "*"
},
{
"name": "kb.groups",
"value": "hadoop,users,localusers"
},
{
"name": "proxy.groups",
"value": "group1, group2, group3, group4, group5"
},
{
"name": "internal.user.groups",
"value": "group1, group2"
},
{
"name": "internal.groups",
"value": "none"
}
]
}
我需要根据以下规则进行合并:
如果两个文件中list(key2)
中的'name'键匹配,则将这些值连接起来。
例如
文件1:
"key2": [{"name" : "firstname", "value" : "bob"}]
文件2:
"key2": [{"name" : "firstname", "value" : "charlie"}]
最终输出:
"key2": [{"name" : "firstname", "value" : "bob, charlie"}]
附加值时的一些注意事项:
如果两个文件在“ value”中均包含重复的值,则最终结果应仅为值的并集。
如果任何“值”包含“ *”,则最终值应为“ *”。
我已经编写了一个python脚本来加载两个JSON文件并合并它们,但似乎只是将所有内容连接到了第一个JSON文件中。
def merge(a, b):
"merges b into a"
for key in b:
if key in a:# if key is in both a and b
if key == "key1":
pass
elif key == "key2":
for d1, d2 in zip(a[key], b[key]):
for key, value in d1.items():
if value != d2[key]:
a.append({"name": d2[key], "value": d2["value"]})
else:
a[key] = a[key]+ b[key]
else: # if the key is not in dict a , add it to dict a
a.update({key:b[key]})
return a
有人可以指出我如何比较两个文件中“名称”部分的值和key2的列表,并将“值”中的值连接起来吗?
答案 0 :(得分:2)
这是一个使用字典以线性时间运行的解决方案,该字典通过给定a
键在name
中快速查找项目。字典b
的{{1}}列表经过一次迭代,并且key2
根据需要在恒定时间内进行修改。集合用于消除重复项并处理星号。
a
示例输出:
def merge(a, b):
lookup = {o['name']: o for o in a['key2']}
for e in a['key2']:
e['value'] = set([x.strip() for x in e['value'].split(",")])
for e in b['key2']:
if e['name'] in lookup:
lookup[e['name']]['value'].update([x.strip() for x in e['value'].split(",")])
else:
e['value'] = set([x.strip() for x in e['value'].split(",")])
a['key2'].append(e)
for e in a['key2']:
if "*" in e['value']:
e['value'] = "*"
else:
e['value'] = ", ".join(sorted(list(e['value'])))
还有一个测试repl。
答案 1 :(得分:1)
不能保证a["key2"]
和b["key2"]
中元素的顺序相同,因此您应该建立一个从"name"
值到a["key2"]
中索引的映射,然后浏览b["key2"]
,将每个"name"
值与该字典进行比较。
代码可能是:
def merge(a, b):
"merges b into a"
for key in b:
if key in a:# if key is in both a and b
if key == "key2":
# build a mapping from names from a[key2] to the member index
akey2 = { d["name"]: i for i,d in enumerate(a[key]) }
for d2 in b[key]: # browse b["key2"]
if d2["name"] in akey2: # a name from a["key2"] matches
a[key][akey2[d2["name"]]]["value"] += ", " + d2["value"]
else:
a[key].append(d2) # when no match
else: # if the key is not in dict a , add it to dict a
a[key] = b[key]
return a
然后您可以对其进行测试:
a = {"key1": "value1",
"key2": [{"name" : "firstname", "value" : "bob"}]
}
b = {"key1": "value2",
"key2": [{"name" : "firstname", "value" : "charlie"},
{"name" : "foo", "value": "bar"}]
}
merge(a, b)
pprint.pprint(a)
给出预期的结果:
{'key1': 'value1',
'key2': [{'name': 'firstname', 'value': 'bob, charlie'},
{'name': 'foo', 'value': 'bar'}]}
答案 2 :(得分:0)
如果它不在新字典中,则只需遍历键即可;如果将两个值合并,则将其添加进来
d1 = {"name" : "firstname", "value" : "bob"}
d2 = {"name" : "firstname", "value" : "charlie"}
d3 = {}
for i in d1:
for j in d2:
if i not in d3:
d3[i] = d1[i]
else:
d3[i] = '{}, {}'.format(d1[i], d2[i])
print(d3)
(xenial)vash@localhost:~/python/stack_overflow$ python3.7 formats.py {'name': 'firstname, firstname', 'value': 'bob, charlie'}