嵌套列表过滤、合并及多字段求和实现求助
解决嵌套列表按前三个元素分组并对后三个元素分别求和的问题
方法1:基于itertools.groupby改进原代码
你的原代码已经用到了groupby,只需扩展逻辑即可实现多字段求和:
from itertools import groupby from operator import itemgetter in_list = [ ['p0-1', 'p1-1', 'p2-1', 1, 1, 2], ['p0-1', 'p1-1', 'p2-1', 2, 1, 1], ['p0-1', 'p1-1', 'p2-1', 1, 2, 1], ['p0-2', 'p1-1', 'p2-1', 1, 1, 1], ['p0-2', 'p1-2', 'p2-1', 1, 1, 1], ['p0-2', 'p1-1', 'p2-2', 1, 1, 1] ] # 改进后的groupby实现 out_list = [ list(key) + [sum(col) for col in zip(*group)][3:] for key, group in groupby(sorted(in_list), key=itemgetter(0, 1, 2)) ] print(out_list)
逻辑说明:
sorted(in_list)确保相同分组的元素连续(groupby仅对连续的相同key分组)zip(*group)将分组内的所有元素按列打包,比如第四个元组对应所有q3值,第五个对应q4,第六个对应q5[sum(col) for col in zip(*group)][3:]对后三列分别求和list(key)将分组key的元组转为列表,再与求和结果拼接成最终子列表
方法2:使用字典分组(更高效)
如果数据量较大,groupby的排序开销会偏高,用字典直接分组的时间复杂度为O(n),效率更高:
from collections import defaultdict in_list = [ ['p0-1', 'p1-1', 'p2-1', 1, 1, 2], ['p0-1', 'p1-1', 'p2-1', 2, 1, 1], ['p0-1', 'p1-1', 'p2-1', 1, 2, 1], ['p0-2', 'p1-1', 'p2-1', 1, 1, 1], ['p0-2', 'p1-2', 'p2-1', 1, 1, 1], ['p0-2', 'p1-1', 'p2-2', 1, 1, 1] ] group_dict = defaultdict(lambda: [0, 0, 0]) for item in in_list: # 用前三个元素的元组作为分组key key = tuple(item[:3]) # 累加后三个字段的值 group_dict[key][0] += item[3] group_dict[key][1] += item[4] group_dict[key][2] += item[5] # 转换为期望的列表格式 out_list = [list(key) + vals for key, vals in group_dict.items()] print(out_list)
逻辑说明:
defaultdict(lambda: [0,0,0])自动为每个新分组初始化三个求和计数器- 遍历每个元素,按前三个元素的元组作为key,累加对应字段的和
- 最后将字典的key和值拼接成目标格式的列表
输出结果
两种方法均会生成你期望的结果:
[ ['p0-1', 'p1-1', 'p2-1', 4, 4, 4], ['p0-2', 'p1-1', 'p2-1', 1, 1, 1], ['p0-2', 'p1-2', 'p2-1', 1, 1, 1], ['p0-2', 'p1-1', 'p2-2', 1, 1, 1] ]
内容的提问来源于stack exchange,提问作者Dmitry R.
相关产品推荐
相关产品推荐

