如何使用 Python 从 json 返回算术表达式的结果?

2019-10-06 18:13:42 +08:00
 rickyleegee

新人学 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 的值而已, 并没有做任何的递归. 请问要怎么写才可以呢??

3187 次点击
所在节点    Python
8 条回复
necomancer
2019-10-06 19:10:05 +08:00
你去搜搜波兰表达式怎么算。或者看看算法的书。应该是转成个二叉树吧。
necomancer
2019-10-06 19:12:45 +08:00
或者后缀记法,用栈。
lalalakakaka
2019-10-06 21:49:05 +08:00
勇气可嘉,参考:wangyin 《 DSL 的误区 》
python 格式的运算式语法多简单易懂啊,直接写运算式,过滤一下然后 eval 不好么~
aijam
2019-10-07 03:18:09 +08:00
啥叫递归?递归至少要调用自己阿。。。
rickyleegee
2019-10-07 08:53:22 +08:00
@lalalakakaka 請問怎麼過濾?
lalalakakaka
2019-10-07 10:08:14 +08:00
@rickyleegee 本来我的意思是直接

expr_str = """(2*3)+(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(s*sub_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 语法格式多蛋疼~
lalalakakaka
2019-10-07 10:21:10 +08:00
我操,缩进没了~我又上不去 gist,好绝望
lalalakakaka
2019-10-07 10:27:00 +08:00
aHR0cHM6Ly9naXRlZS5jb20vaWNlX3dhdmUvY29kZXMvYXk2ajVyM2lidDR6dTJmeHEwazh3NTU=

base64 解码一下就能看到地址

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/606607

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX