如何在Python中归并含重复ID的对象数组?
解决思路与代码实现
你原来的reduce用法不对,因为Python里字典不能直接用+拼接,这和JS里的逻辑不一样。正确的做法和JS中用reduce聚合的思路一致:先通过reduce把相同ID的项聚合到一个临时字典里(用ID作为键),最后再把字典的值转换成目标数组。
以下是可行的代码:
from functools import reduce original_list = [ { "id": '111', "error": "MissingError", "message": "Missing data", "type": "red", }, { "id": '111', "error": "Warning", "message": "Missing attribute", "type": "red", }, { "id": '222', "error": "MissingError", "message": "Missing data", "type": "yellow" } ] # 用reduce聚合相同ID的项 aggregated = reduce(lambda acc, item: { **acc, item["id"]: { "id": item["id"], "type": item["type"], "messages": [ *(acc[item["id"]]["messages"] if item["id"] in acc else []), {"error": item["error"], "message": item["message"]} ] } }, original_list, {}) # 把字典的值转换成数组,得到预期结果 result = list(aggregated.values()) print(result)
代码说明
- 初始值
{}是一个空字典,用来存储以ID为键的聚合结果; - 每次迭代时,先检查当前项的ID是否已在聚合字典中:
- 若存在,就取出已有的
messages数组,追加当前项的error和message组成的新对象; - 若不存在,就创建一个新的条目,初始化
messages数组并放入当前项的错误信息;
- 若存在,就取出已有的
- 最后用
list(aggregated.values())把字典里的聚合值转换成数组,就是你要的预期格式。
另外,如果你觉得reduce的写法有点绕,Python里还有更直观的写法,用普通循环实现,新手更容易理解:
original_list = [ # 原始数据同上 ] aggregated = {} for item in original_list: item_id = item["id"] if item_id not in aggregated: aggregated[item_id] = { "id": item_id, "type": item["type"], "messages": [] } aggregated[item_id]["messages"].append({ "error": item["error"], "message": item["message"] }) result = list(aggregated.values())
这个循环写法逻辑和reduce版本完全一致,但是可读性更高,适合Python新手。
内容的提问来源于stack exchange,提问作者cafe123
相关产品推荐
相关产品推荐

