优雅实现嵌套JSON算术表达式的递归求值方法
优化嵌套算术表达式的递归计算函数
首先看你的需求:处理类似["+", 1, ["+", 3,["+", 3,4]]]这样的嵌套算术表达式,通过递归计算得到结果(这里预期是11)。先拆解下现有代码的几个小问题:
- 原地修改输入的
exp列表,这可能会意外改变原始数据,不是最佳实践; eval_numberExpression里的idx == len(exp)判断永远不会成立(因为enumerate的索引范围是0到len(exp)-1),导致该分支逻辑完全无效;- 拆分两个函数有点冗余,其实可以合并成一个更简洁的递归函数。
下面是更优雅的实现方式,核心思路是用单一递归函数处理所有情况:
def eval_expression(exp): # 如果是数字,直接返回其值 if isinstance(exp, (int, float)): return exp # 如果是表达式列表,取出运算符和操作数 op = exp[0] # 递归计算左右两个操作数的最终值 left_val = eval_expression(exp[1]) right_val = eval_expression(exp[2]) # 根据运算符执行计算 if op == "+": return left_val + right_val elif op == "-": return left_val - right_val elif op == "*": return left_val * right_val elif op == "/": # 可根据需求添加除零错误处理,这里先保持基础逻辑 return left_val / right_val else: raise ValueError(f"不支持的运算符: {op}")
测试你的示例:
d = ["+", 1, ["+", 3,["+", 3,4]]] print(eval_expression(d)) # 输出 11,符合预期
这个实现的优势:
- 无副作用:不会修改原始输入的表达式列表,所有计算都基于递归返回的新值,避免意外污染原数据;
- 逻辑直观:递归逻辑清晰——遇到数字直接返回,遇到表达式就拆解为运算符+左右操作数,分别递归计算后再合并结果;
- 可扩展性:如果要添加新运算符,只需在条件分支中补充对应逻辑即可;
- 严谨性:新增了未知运算符的报错逻辑,比原代码的默认分支更健壮。
如果你想让代码更紧凑,还可以用运算符映射表替代冗长的if-elif链,借助Python标准库进一步简化:
import operator def eval_expression(exp): if isinstance(exp, (int, float)): return exp # 运算符与对应计算函数的映射 op_map = { "+": operator.add, "-": operator.sub, "*": operator.mul, "/": operator.truediv } op = exp[0] try: calc_func = op_map[op] except KeyError: raise ValueError(f"不支持的运算符: {op}") # 递归计算操作数后执行对应函数 return calc_func(eval_expression(exp[1]), eval_expression(exp[2]))
这个版本利用operator模块将运算符和内置计算函数绑定,代码更简洁,可读性也更强,同时保留了完整的错误处理逻辑。
内容的提问来源于stack exchange,提问作者ilaunchpad
相关产品推荐
相关产品推荐

