Python如何按name字段合并字典列表同组的字段值?
问题描述
现有如下格式的字典列表:
data = [ { 'name': 'First Filter', 'nut': '122222', 'cpv': '111' }, { 'name': 'First Filter', 'nut': '122222', 'cpv': '123' }, { 'name': 'First Filter', 'nut': '123-41', 'cpv': '111' }, { 'name': 'First Filter', 'nut': '123-41', 'cpv': '123' }, { 'name': 'second Filter', 'nut': '123-41', 'cpv': '123' } ]
需要实现的逻辑:以name字段为分组依据,将相同name值下的nut、cpv字段值去重后合并为列表,最终输出格式如下:
[ { 'name': 'First Filter', 'nut': ['122222', '123-41'], 'cpv': ['111', '123'] }, { 'name': 'second Filter', 'nut': ['123-41'], 'cpv': ['123'] } ]
尝试用pandas DataFrame实现未成功,下面给出两种可直接运行的实现方案。
实现方案
方案1:纯Python原生实现
不需要安装任何第三方依赖,运行效率高,适合数据量中等及以下的场景:
from collections import defaultdict # 初始化分组容器,每个name对应nut和cpv的集合,自动完成去重 group_map = defaultdict(lambda: {"nut": set(), "cpv": set()}) for item in data: name = item["name"] group_map[name]["nut"].add(item["nut"]) group_map[name]["cpv"].add(item["cpv"]) # 转换为要求的列表格式,将集合转为普通列表 result = [] for name, values in group_map.items(): result.append({ "name": name, "nut": list(values["nut"]), "cpv": list(values["cpv"]) })
Python 3.7+版本字典默认保留插入顺序,输出顺序和原始数据中name首次出现的顺序一致;低版本Python可以用OrderedDict替代普通字典做分组容器保证顺序。
方案2:pandas实现
如果你本身就在用pandas做数据流程处理,可以直接用这个写法,之前实现失败基本是聚合步骤没有加去重逻辑,正确代码如下:
import pandas as pd df = pd.DataFrame(data) # 按name分组,每个字段取唯一值后转为列表 result_df = df.groupby("name", as_index=False).agg(lambda x: list(x.unique())) # 转换为字典列表格式 result = result_df.to_dict("records")
注意:如果字段存在空值,
unique()会默认保留空值,不需要空值的话可以在聚合前先调用dropna()处理对应字段。
内容的提问来源于stack exchange,提问作者Muhammad Waqas
相关产品推荐
相关产品推荐

