Python实现科目表层级账户借贷金额向上汇总问题
科目表层级借贷金额向上汇总解决方案
需求说明
我有一个代表科目表层级结构的列表chart_list,包含交易账户和组织账户。借贷金额仅记录在交易账户中,需将这些金额向上汇总至其所属的各级组织账户(通过id与parent_id关联)——子账户的借贷金额累加到父账户,父账户再向上累加至更高级账户。
原代码问题分析
原尝试代码的核心错误是使用each['parent_id'] == each['id']作为字典键,这个判断结果只有True/False两种,无法区分不同账户,完全无法实现层级汇总逻辑。
正确实现方案
思路
- 将所有账户转换为以
id为键的字典,实现父账户的快速查找 - 遍历每个账户,沿着
parent_id向上遍历层级链,将当前账户的借贷金额逐级累加到所有父账户中 - 确保层级链遍历至根节点(
parent_id为None)
代码实现
首先准备包含交易账户数据的测试列表:
chart_list = [ {'id': 2, 'parent_id': None, 'code': '0', 'name': 'ROOT', 'debit': 0, 'credit': 0}, {'id': 3, 'parent_id': 2, 'code': '1', 'name': 'MEIOS FIXOS E INVESTIMENTOS', 'debit': 0, 'credit': 0}, {'id': 4, 'parent_id': 3, 'code': '11', 'name': 'IMOBILIZACOES CORPOREAS', 'debit': 0, 'credit': 0}, {'id': 5, 'parent_id': 4, 'code': '111', 'name': 'Terrenos e recursos naturais', 'debit': 0, 'credit': 0}, {'id': 9, 'parent_id': 5, 'code': '1114', 'name': 'Terrenos com edifícios', 'debit': 15000, 'credit': 0}, # 交易账户 {'id': 13, 'parent_id': 4, 'code': '112', 'name': 'Edifícios e outras construções', 'debit': 0, 'credit': 0}, {'id': 14, 'parent_id': 13, 'code': '1121', 'name': 'Edifícios', 'debit': 0, 'credit': 8000}, # 交易账户 {'id': 21, 'parent_id': 4, 'code': '113', 'name': 'Equipamento básico', 'debit': 0, 'credit': 0}, {'id': 25, 'parent_id': 4, 'code': '114', 'name': 'Equipamentos de carga e transporte', 'debit': 0, 'credit': 0}, ]
汇总逻辑代码:
def aggregate_accounts(chart_list): # 把账户列表转为id映射的字典,方便快速查询父账户 account_dict = {acc['id']: acc.copy() for acc in chart_list} # 遍历每个账户,向上逐级累加金额 for acc in chart_list: current_debit = acc['debit'] current_credit = acc['credit'] parent_id = acc['parent_id'] # 沿着父账户链向上累加,直到根节点 while parent_id is not None: parent_acc = account_dict.get(parent_id) if parent_acc: parent_acc['debit'] += current_debit parent_acc['credit'] += current_credit # 移动到上一级父账户 parent_id = parent_acc['parent_id'] if parent_acc else None # 返回保持原顺序的汇总后账户列表 return [account_dict[acc['id']] for acc in chart_list] # 执行汇总并打印结果 aggregated_result = aggregate_accounts(chart_list) for item in aggregated_result: print(f"ID: {item['id']}, 名称: {item['name']}, 借方: {item['debit']}, 贷方: {item['credit']}")
关键说明
- 使用
account_dict实现O(1)时间复杂度的父账户查找,提升汇总效率 - 遍历每个账户的父链,确保所有上级组织账户都能收到子账户的金额累加
- 通过
acc.copy()创建账户副本,避免修改原始数据 - 循环终止条件为
parent_id为None,确保汇总到根节点
内容的提问来源于stack exchange,提问作者Paulo Matos
相关产品推荐
相关产品推荐

