按键合并字典列表,检查值 - 如果新则添加,如果不同则更新
Merge list of dictionaries by key, check for values - add if new, update if different
我试图摆脱具有相同键的重复字典(通过合并它们),但还需要跟踪它们包含的值。我有 2 个列表:
person_list_1 = [
{"name": "John",
"cars": [
{"make": "Audi", "model_year": 2001},
{"make": "BMW", "model_year": 2009}
]
},
{"name": "Mary",
"cars": [
{"make": "Mazda", "model_year": 2003}
]
},
]
person_list_2 = [
{"name": "John",
"cars": [
{"make": "Audi", "model_year": 2017},
{"make": "Volkswagen", "model_year": 2008}
]
},
{"name": "Ben",
"cars": [
{"make": "Ford", "model_year": 1984}
]
}
]
如您所见,其中两个具有相同的 name
键,但值有点不同。
我希望它最终看起来像这样:
updated_person_list = [
{"name": "John",
"cars": [
{"make": "Audi", "model_year": 2017},
{"make": "BMW", "model_year": 2009},
{"make": "Volkswagen", "model_year": 2008},
]
},
{"name": "Mary",
"cars": [
{"make": "Mazda", "model_year": 2003},
]
},
{"name": "Ben",
"cars": [
{"make": "Ford", "model_year": 1984}
]
},
]
即,在两个列表之间找到匹配的字典键并相应地说明它们 -
如果这样的汽车已经存在于“汽车”列表中但生产年份不同,请更新嵌套字典。
尝试了许多不同的解决方案,包括 collections.defaultdict
、itertools.chain
等,但其中 none 次尝试成功。
有人可以帮忙吗?
你应该遍历字典并在临时字典中累积项目,名称作为键,值作为汽车字典,从品牌到汽车字典,最后我们将这个字典转换为我们想要的字典:
def iterate(acc, l):
for p in l:
name = p["name"]
if not name in acc:
acc[name] = {}
for c in p["cars"]:
acc[name][c["make"]] = c
def merge(l1, l2):
acc = {}
iterate(acc, l1)
iterate(acc, l2)
return acc
def convert(acc):
resp = []
for k, v in acc.items():
resp.append({"name": k, "cars": list(v.values())})
return resp
我们可以将此函数用作:
print(convert(merge(person_list_1, person_list_2)))
结果将是:
[
{'name': 'John', 'cars': [
{'make': 'Audi', 'model_year': 2017},
{'make': 'BMW', 'model_year': 2009},
{'make': 'Volkswagen', 'model_year': 2008}]
},
{'name': 'Mary', 'cars': [
{'make': 'Mazda', 'model_year': 2003}
]
},
{'name': 'Ben', 'cars': [
{'make': 'Ford', 'model_year': 1984}
]
}
]
我试图摆脱具有相同键的重复字典(通过合并它们),但还需要跟踪它们包含的值。我有 2 个列表:
person_list_1 = [
{"name": "John",
"cars": [
{"make": "Audi", "model_year": 2001},
{"make": "BMW", "model_year": 2009}
]
},
{"name": "Mary",
"cars": [
{"make": "Mazda", "model_year": 2003}
]
},
]
person_list_2 = [
{"name": "John",
"cars": [
{"make": "Audi", "model_year": 2017},
{"make": "Volkswagen", "model_year": 2008}
]
},
{"name": "Ben",
"cars": [
{"make": "Ford", "model_year": 1984}
]
}
]
如您所见,其中两个具有相同的 name
键,但值有点不同。
我希望它最终看起来像这样:
updated_person_list = [
{"name": "John",
"cars": [
{"make": "Audi", "model_year": 2017},
{"make": "BMW", "model_year": 2009},
{"make": "Volkswagen", "model_year": 2008},
]
},
{"name": "Mary",
"cars": [
{"make": "Mazda", "model_year": 2003},
]
},
{"name": "Ben",
"cars": [
{"make": "Ford", "model_year": 1984}
]
},
]
即,在两个列表之间找到匹配的字典键并相应地说明它们 - 如果这样的汽车已经存在于“汽车”列表中但生产年份不同,请更新嵌套字典。
尝试了许多不同的解决方案,包括 collections.defaultdict
、itertools.chain
等,但其中 none 次尝试成功。
有人可以帮忙吗?
你应该遍历字典并在临时字典中累积项目,名称作为键,值作为汽车字典,从品牌到汽车字典,最后我们将这个字典转换为我们想要的字典:
def iterate(acc, l):
for p in l:
name = p["name"]
if not name in acc:
acc[name] = {}
for c in p["cars"]:
acc[name][c["make"]] = c
def merge(l1, l2):
acc = {}
iterate(acc, l1)
iterate(acc, l2)
return acc
def convert(acc):
resp = []
for k, v in acc.items():
resp.append({"name": k, "cars": list(v.values())})
return resp
我们可以将此函数用作:
print(convert(merge(person_list_1, person_list_2)))
结果将是:
[
{'name': 'John', 'cars': [
{'make': 'Audi', 'model_year': 2017},
{'make': 'BMW', 'model_year': 2009},
{'make': 'Volkswagen', 'model_year': 2008}]
},
{'name': 'Mary', 'cars': [
{'make': 'Mazda', 'model_year': 2003}
]
},
{'name': 'Ben', 'cars': [
{'make': 'Ford', 'model_year': 1984}
]
}
]