You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python标准库更优雅地实现周数据按月分组汇总?

嘿,我来帮你优化这段代码!你的原问题很典型——依赖输入列表按月份有序才能正确分组,一旦数据顺序打乱,结果就会出错,咱们用Python标准库就能写出更优雅、更健壮的实现,完全符合Pythonic风格~

问题分析

原代码的核心问题是必须依赖输入数据按月份连续排列,如果中间插入了其他月份的条目(比如把('2020/03/15', 56)放到2月的条目后面),就会错误地重复创建分组,导致汇总结果出错。接下来给你两种标准库的解决方案:


方案1:用collections.defaultdict(不依赖数据顺序)

这种方法最直观,不需要提前排序,直接遍历累加每个月份的值,时间复杂度是O(n),效率很高:

from collections import defaultdict

sum_weekly = [('2020/01/05', 59), ('2020/01/19', 88), ('2020/01/26', 95), ('2020/02/02', 89), ('2020/02/09', 113), ('2020/02/16', 90), ('2020/02/23', 68), ('2020/03/01', 74), ('2020/03/08', 85), ('2020/04/19', 6), ('2020/04/26', 5), ('2020/05/03', 14), ('2020/05/10', 5), ('2020/05/17', 20), ('2020/05/24', 28),('2020/03/15', 56), ('2020/03/29', 5), ('2020/04/12', 2),]

# 初始化一个默认值为0的字典,用来存每个月份的累加值
monthly_sum = defaultdict(int)
for date_str, value in sum_weekly:
    # 提取日期中的月份部分
    month = date_str.split('/')[1]
    monthly_sum[month] += value

# 如果需要按月份顺序输出,用sorted排序;不需要的话直接转成list即可
out = sorted(monthly_sum.items(), key=lambda x: x[0])
print(out)
# 输出:[('01', 242), ('02', 360), ('03', 220), ('04', 13), ('05', 67)]

优势:完全不依赖输入顺序,处理无序数据时更高效,逻辑清晰易懂。


方案2:用itertools.groupby(简洁的分组写法,需先排序)

如果你的数据可以接受先排序(或者本身就是有序的),groupby配合列表推导式的写法非常简洁,很有Python风格:

from itertools import groupby

sum_weekly = [('2020/01/05', 59), ('2020/01/19', 88), ('2020/01/26', 95), ('2020/02/02', 89), ('2020/02/09', 113), ('2020/02/16', 90), ('2020/02/23', 68), ('2020/03/01', 74), ('2020/03/08', 85), ('2020/04/19', 6), ('2020/04/26', 5), ('2020/05/03', 14), ('2020/05/10', 5), ('2020/05/17', 20), ('2020/05/24', 28),('2020/03/15', 56), ('2020/03/29', 5), ('2020/04/12', 2),]

# 先按月份对数据排序,因为groupby只能将连续的相同键分到一组
sorted_weekly = sorted(sum_weekly, key=lambda x: x[0].split('/')[1])

# 按月份分组,同时计算每组的总和
out = [
    (month, sum(value for _, value in group)) 
    for month, group in groupby(sorted_weekly, key=lambda x: x[0].split('/')[1])
]

print(out)
# 输出同样是:[('01', 242), ('02', 360), ('03', 220), ('04', 13), ('05', 67)]

优势:代码简洁紧凑,用列表推导式完成分组+求和,符合Python的“简洁至上”原则。


两种方案对比

  • 如果数据是无序的,优先选defaultdict,效率更高(O(n) vs O(n log n)的排序开销);
  • 如果数据本身有序,或者你需要保持分组后的顺序和原有序列表一致,groupby的写法更优雅。

内容的提问来源于stack exchange,提问作者rush dee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 20:52:49