如何用Python将无缩进财务数据按规则构建嵌套字典树
问题描述
给定无缩进的财务数据,仅通过Total关键词识别节点并构建树形结构:
Current Assets Cash Checking 583961 Savings 224600 Petty Cash 89840 Total Cash 898402 Accounts Receivable 3593607 Work in Process 589791 Other Current Assets Prepaid Rent 164593 Prepaid Liability Insurance 109728 Total Other Current Assets 274321 Total Current Assets 274321
期望输出的JSON结构:
{ "Current Assets": { "Cash": { "Checking": 583961, "Savings": 224600, "Petty Cash": 89840, "Total Cash": 898402 }, "Accounts Receivable": 3593607, "Work in Process": 589791, "Other Current Assets": { "Prepaid Rent": 164593, "Prepaid Liability Insurance": 109728, "Total Other Current Assets": 274321 }, "Total Current Assets": 5356121 } }
规则说明
- 末尾带数值的条目(如Accounts Receivable)无子节点;
- 末尾无数值的条目(如Cash)为父节点,直到对应Total条目出现时结束层级;
- Work in Process是Current Assets的直接子项,非Accounts Receivable的子项。
Python实现方案
使用栈结构管理层级关系,栈中保存当前层级的父节点及其名称,遍历每行数据时判断类型(父节点/子项/Total节点),动态调整层级或添加数据:
import json def build_financial_tree(data_lines): root = {} # 栈元素格式:(当前父节点对象, 父节点名称) stack = [] current_parent = root for line in data_lines: line = line.strip() if not line: continue parts = line.split(maxsplit=1) if len(parts) == 1: # 无数值,为父节点,创建空字典作为子节点 parent_name = parts[0] current_parent[parent_name] = {} stack.append((current_parent, parent_name)) current_parent = current_parent[parent_name] else: name, value = parts value = int(value) if name.startswith("Total"): # 遇到Total节点,添加后回到上一层级 current_parent[name] = value if stack: current_parent, _ = stack.pop() else: # 普通子项,直接添加到当前父节点 current_parent[name] = value return root # 测试数据 raw_data = """Current Assets Cash Checking 583961 Savings 224600 Petty Cash 89840 Total Cash 898402 Accounts Receivable 3593607 Work in Process 589791 Other Current Assets Prepaid Rent 164593 Prepaid Liability Insurance 109728 Total Other Current Assets 274321 Total Current Assets 274321 """.splitlines() financial_tree = build_financial_tree(raw_data) # 格式化输出JSON print(json.dumps(financial_tree, indent=4))
代码说明
- 栈的核心作用:追踪当前层级的父节点,遇到父节点时压栈切换层级,遇到Total节点时出栈返回上一级,确保后续条目归到正确的父节点下。
- 行处理逻辑:
- 拆分每行数据,区分父节点(仅名称)、普通子项(名称+数值)、Total节点(以Total开头的名称+数值);
- 普通子项直接挂载到当前父节点;
- Total节点挂载后,自动切换回上一层父节点,避免后续条目错误进入子层级。
- 补充:原测试数据中
Total Current Assets的输入值274321为计算错误,实际应为5356121(898402+3593607+589791+274321),若需自动计算Total值,可在出栈时遍历子节点求和替换,此处保留原输入逻辑。
内容的提问来源于stack exchange,提问作者prashant thakre
相关产品推荐
相关产品推荐

