基于嵌套字典proj值拆分列表的更优实现方案咨询
根据嵌套字典的
proj值拆分列表的优化实现 问题背景
原始数据结构:
[[{'proj': 'XABCD'}, {'test': 1}], [{'proj': 'XABCD'}, {'test': 2}], [{'proj': 'XDEFG'}, {'test': 1}]]
需求:根据嵌套字典中proj的值拆分主列表,得到每个唯一项目对应的子列表,预期结果:
[[{'proj': 'XABCD'}, {'test': 1}], [{'proj': 'XABCD'}, {'test': 2}]] [[{'proj': 'XDEFG'}, {'test': 1}]]
由于项目数量和名称未知,无法硬编码排序逻辑,已通过循环实现该功能,代码及结果如下:
contaminated_samples = [[{'proj': 'XABCD'}, {'test': 1}], [{'proj': 'XABCD'}, {'test': 2}], [{'proj': 'XDEFG'}, {'test': 1}]] projects = {} for sample in contaminated_samples: proj = sample[0]['proj'] if proj in projects.keys(): projects[proj].append(sample) else: projects[proj] = [sample] # 输出结果 # {'XABCD': [[{'proj': 'XABCD'}, {'test': 1}], [{'proj': 'XABCD'}, {'test': 2}]], 'XDEFG': [[{'proj': 'XDEFG'}, {'test': 1}]]}
现需要更高效的实现方式或可达成相同效果的列表/字典推导式。
优化实现方案
1. 使用collections.defaultdict简化循环逻辑
defaultdict可以省去判断键是否存在的步骤,代码更简洁,执行效率优于原循环(避免了重复的keys()查询):
from collections import defaultdict contaminated_samples = [[{'proj': 'XABCD'}, {'test': 1}], [{'proj': 'XABCD'}, {'test': 2}], [{'proj': 'XDEFG'}, {'test': 1}]] projects = defaultdict(list) for sample in contaminated_samples: proj = sample[0]['proj'] projects[proj].append(sample) # 若需转为普通字典,执行:dict(projects)
2. 结合itertools.groupby实现分组
如果先对数据按proj值排序,可直接用groupby分组,适合需要有序输出的场景:
from itertools import groupby contaminated_samples = [[{'proj': 'XABCD'}, {'test': 1}], [{'proj': 'XABCD'}, {'test': 2}], [{'proj': 'XDEFG'}, {'test': 1}]] # groupby要求连续的相同元素才能分组,因此需先排序 sorted_samples = sorted(contaminated_samples, key=lambda x: x[0]['proj']) projects = {k: list(v) for k, v in groupby(sorted_samples, key=lambda x: x[0]['proj'])}
注意:若原始数据中同proj的元素已连续排列,可跳过排序步骤,进一步提升效率。
3. 纯字典推导式实现(小数据量适用)
纯推导式无法动态追加元素,需先提取所有唯一proj值再逐个筛选,缺点是会遍历原始数据多次,大数据量下效率较低:
contaminated_samples = [[{'proj': 'XABCD'}, {'test': 1}], [{'proj': 'XABCD'}, {'test': 2}], [{'proj': 'XDEFG'}, {'test': 1}]] projects = { proj: [sample for sample in contaminated_samples if sample[0]['proj'] == proj] for proj in {sample[0]['proj'] for sample in contaminated_samples} }
总结
- 追求简洁高效:优先使用
collections.defaultdict,代码简洁且性能最优。 - 数据已按
proj连续排列:选择itertools.groupby更合适。 - 小数据量场景:纯字典推导式可快速实现,但不推荐用于大数据量。
内容的提问来源于stack exchange,提问作者kevin41
相关产品推荐
相关产品推荐

