首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
rickyleegee
V2EX  ›  Python

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

  •  
  •   rickyleegee · 114 天前 · 1536 次点击
    这是一个创建于 114 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    necomancer
        1
    necomancer   114 天前
    你去搜搜波兰表达式怎么算。或者看看算法的书。应该是转成个二叉树吧。
    necomancer
        2
    necomancer   114 天前
    或者后缀记法,用栈。
    lalalakakaka
        3
    lalalakakaka   114 天前
    勇气可嘉,参考:wangyin 《 DSL 的误区 》
    python 格式的运算式语法多简单易懂啊,直接写运算式,过滤一下然后 eval 不好么~
    aijam
        4
    aijam   114 天前
    啥叫递归?递归至少要调用自己阿。。。
    rickyleegee
        5
    rickyleegee   114 天前 via iPhone
    @lalalakakaka 請問怎麼過濾?
    lalalakakaka
        6
    lalalakakaka   114 天前   ♥ 1
    @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
        7
    lalalakakaka   114 天前
    我操,缩进没了~我又上不去 gist,好绝望
    lalalakakaka
        8
    lalalakakaka   114 天前
    aHR0cHM6Ly9naXRlZS5jb20vaWNlX3dhdmUvY29kZXMvYXk2ajVyM2lidDR6dTJmeHEwazh3NTU=

    base64 解码一下就能看到地址
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2293 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 25ms · UTC 08:06 · PVG 16:06 · LAX 00:06 · JFK 03:06
    ♥ Do have faith in what you're doing.