Python函数返回嵌套字典错误:如何按周期统计收支及总文档数?
问题描述
需要实现task_2函数,返回按周期统计的收支及总文档数的嵌套字典,要求:
- 按周期汇总
incomes、expenses及总文档数(total = incomes + expenses) - 禁止修改函数体外代码、禁止额外导入模块
- 若周期范围存在缺失月份,该周期的文档数视为0
示例输入数据:
[ { "package": "FLEXIBLE", "created": "2020-03-10T00:00:00", "summary": [ { "period": "2019-12", "documents": { "incomes": 63, "expenses": 13 } }, { "period": "2020-02", "documents": { "incomes": 45, "expenses": 81 } } ] }, { "package": "ENTERPRISE", "created": "2020-03-19T00:00:00", "summary": [ { "period": "2020-01", "documents": { "incomes": 15, "expenses": 52 } }, { "period": "2020-02", "documents": { "incomes": 76, "expenses": 47 } } ] } ]
当前实现代码:
def task_2(data_in): ''' Return number of documents per period (incomes, expenses, total). ex. { '2020-04': { 'incomes': 2480, 'expenses': 2695, 'total': 5175 }, '2020-05': { 'incomes': 2673, 'expenses': 2280, 'total': 4953 } } ''' period = [] for term in data_in: for dict_val in term['summary']: if dict_val['period'] in period: continue else: period.append(dict_val['period']) incomes = [] for term in data_in: for dict_val in term['summary']: incomes.append(dict_val['documents']['incomes']) expenses = [] for term in data_in: for dict_val in term['summary']: expenses.append(dict_val['documents']['expenses']) return {per: {"incomes": inc, "expenses": exp, "total": inc + exp} for per, inc, exp in zip(period, range(len(incomes)), range(len(expenses)))}
错误输出:
{'2019-12': {'incomes': 1, 'expenses': 1, 'total': 2}, '2020-02': {'incomes': 2, 'expenses': 2, 'total': 4}}
问题分析
- 未按周期累加数据:当前代码仅收集了零散的周期和收支值,未对同一周期的收支进行汇总,返回时错误使用
range(len(incomes))取索引值,导致输出数字而非实际收支金额。 - 未处理缺失周期:没有生成完整的连续周期序列,缺失的月份未被纳入统计范围。
修复方案
def task_2(data_in): ''' Return number of documents per period (incomes, expenses, total). ex. { '2020-04': { 'incomes': 2480, 'expenses': 2695, 'total': 5175 }, '2020-05': { 'incomes': 2673, 'expenses': 2280, 'total': 4953 } } ''' # 1. 按周期累加收支数据 period_data = {} for term in data_in: for summary_item in term['summary']: period = summary_item['period'] docs = summary_item['documents'] if period not in period_data: period_data[period] = {'incomes': 0, 'expenses': 0} period_data[period]['incomes'] += docs['incomes'] period_data[period]['expenses'] += docs['expenses'] if not period_data: return {} # 2. 生成完整的连续周期序列 # 将周期转换为(year, month)元组用于排序和生成连续月份 sorted_periods = sorted([(int(p.split('-')[0]), int(p.split('-')[1])) for p in period_data.keys()]) start_year, start_month = sorted_periods[0] end_year, end_month = sorted_periods[-1] full_periods = [] current_year, current_month = start_year, start_month while (current_year, current_month) <= (end_year, end_month): full_periods.append(f"{current_year}-{current_month:02d}") # 月份进位处理 if current_month == 12: current_year += 1 current_month = 1 else: current_month += 1 # 3. 构建最终结果,缺失周期填0 result = {} for period in full_periods: incomes = period_data.get(period, {}).get('incomes', 0) expenses = period_data.get(period, {}).get('expenses', 0) result[period] = { 'incomes': incomes, 'expenses': expenses, 'total': incomes + expenses } return result
代码说明
- 数据累加:用字典
period_data按周期存储收支总和,遍历输入数据时自动累加同一周期的收支数值。 - 生成完整周期:将所有周期转换为可排序的(year, month)元组,找到首尾周期后,生成中间所有连续月份的字符串格式。
- 结果构建:遍历完整周期列表,从
period_data中提取对应数据,缺失周期用0填充,同时计算total值。
内容的提问来源于stack exchange,提问作者Marek Grzesiak
相关产品推荐
相关产品推荐

