如何使用 Python 从 JSON 返回算术表达式的结果?
新人学 Python,我想写一个 Python 程序,该程序可以采用 JSON 格式的嵌套表达式,解析和评估答案.
比如這一個 json 文件 { "root": { "description": "This is your first nested expression, and it evaluates to 8. If you have difficulties understanding it, it reads (2*3)+(4-2).", "plus": [{ "times": [{ "int": 2 }, { "int": 3 }] }, { "minus": [{ "int": 4 }, { "int": 2 }] }] } }
像 PLUS 这样的每个运算符都至少使用 2 个参数,MINS 和 TIMES 恰好采用 2 个参数.
我尝试了这样来写
def operation(d):
if isinstance(d,dict):
s = 0
addition = d.get('root').get('plus')
for i in addition:
s+=int(i["int"])
return s
result = operation(z)
当我发现了这样只是返回了 int 的值而已, 并没有做任何的递归. 请问要怎么写才可以呢??
如何使用 Python 从 JSON 返回算术表达式的结果?
你去搜搜波兰表达式怎么算。或者看看算法的书。应该是转成个二叉树吧。
import json
import operator
def evaluate_expression(data):
"""
从JSON数据中解析并计算算术表达式
Args:
data: 包含表达式的JSON字符串或字典
Returns:
计算结果
"""
# 如果是字符串,先解析为字典
if isinstance(data, str):
data = json.loads(data)
# 支持的运算符映射
operators = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'/': operator.truediv,
'**': operator.pow,
'%': operator.mod
}
def _evaluate(node):
"""递归计算表达式树"""
if isinstance(node, (int, float)):
return node
if isinstance(node, list) and len(node) == 3:
op, left, right = node
if op in operators:
return operators[op](_evaluate(left), _evaluate(right))
else:
raise ValueError(f"不支持的运算符: {op}")
raise ValueError(f"无效的表达式节点: {node}")
return _evaluate(data)
# 使用示例
if __name__ == "__main__":
# 示例1: 直接使用字典
expr1 = ["+", 5, ["*", 3, 2]] # 5 + (3 * 2)
print(f"5 + (3 * 2) = {evaluate_expression(expr1)}") # 输出: 11
# 示例2: 使用JSON字符串
expr2_json = '["-", ["**", 2, 3], ["/", 10, 2]]' # 2^3 - (10/2)
print(f"2^3 - (10/2) = {evaluate_expression(expr2_json)}") # 输出: 3.0
# 示例3: 复杂表达式
expr3 = ["+", ["*", 2, 3], ["-", 10, ["/", 8, 2]]] # (2*3) + (10 - (8/2))
print(f"(2*3) + (10 - (8/2)) = {evaluate_expression(expr3)}") # 输出: 12.0
这个方案用前缀表达式(波兰表示法)来存储表达式,每个运算都是 [运算符, 左操作数, 右操作数] 的三元列表。evaluate_expression 函数递归解析这个结构,用 operator 模块执行实际计算。
表达式可以写成字典直接传进去,或者用JSON字符串也行。代码里 operators 字典定义了支持的运算符,要加别的运算符(比如 // 整除)直接往里面加映射就行。
注意除法和乘方运算返回的是浮点数,整数除法得用 // 运算符。
用递归遍历表达式树,遇到数字就返回,遇到运算就递归算左右两边再计算。
或者后缀记法,用栈。
啥叫递归?递归至少要调用自己阿。。。
請問怎麼過濾?
本来我的意思是直接
expr_str = “”"(23)+(4-2)"""
ans = eval(expr_str)
后来发现你好像是在做 python 题学习递归,假期要结束了,刚好蛋疼给你写了个答案:
# -- coding: utf-8 --
import json
def is_raw_type(d : dict) -> bool:
type_words = [‘int’]
for k in d.keys():
if k not in type_words:
return False
return True
def is_basic_expr(d : dict) -> bool:
op_words = [‘plus’, ‘times’, ‘minus’]
if len(d.keys()) != 1:
return False
else:
k,v = d.copy().popitem()
if k in op_words:
if isinstance(v,dict):
return is_raw_type(v)
if isinstance(v,list):
return (sum([not is_raw_type(kv) for kv in v]) == 0)
def calc_parser(d : dict):
if is_raw_type(d):
return d
elif is_basic_expr(d):
k,v = d.popitem()
if k == “plus”:
return {‘int’:sum([int(sub_v[‘int’]) for sub_v in v])}
elif k == “minus”:
return {‘int’:v[0][‘int’]-v[1][‘int’]}
elif k == “times”:
s = 1
for sub_v in v:
s = int(ssub_v[‘int’])
return {‘int’:s}
else:
return {‘int’:0}
elif len(d.keys()) == 1:
e = d.copy()
k,v = d.popitem()
e[k] = [calc_parser(sub_v) for sub_v in v]
return calc_parser(e)
test = “”"{ “root”: { “description”: “This is your first nested expression, and it evaluates to 8. If you have difficulties understanding it, it reads (2*3)+(4-2).”, “plus”: [{ “times”: [{ “int”: 2 }, { “int”: 3 }] }, { “minus”: [{ “int”: 4 }, { “int”: 2 }] }] } }"""
d_with_description = json.loads(test)
for k,v in d_with_description[‘root’].items():
if k != ‘description’:
d = {k:v}
print(calc_parser(d))
这也是为了证明题中自己发明的那种自定义 json 语法格式多蛋疼~
我操,缩进没了~我又上不去 gist,好绝望


