如何解析这样的字典结构(类似前缀表示法)转化为需要的字符串形式

 data={
    "or":{
        "=":{
            "name": ["aaa", "bbb"]
        }, 
        ">": {
           "age": [1, 2, 3]
        }
    }
}

字典结构类似于lisp的那种结构(+ 2 3 (× 4 5))前缀表示法

然后把这种嵌套的结构,解析成还原成一般的结构,字符串,像这样。
“name = aaa or name = bbb or age > 1 or age > 2 or age > 3”

也许实际用不到这么复杂的结构。

阅读 6k
3 个回答

就算每种操作符的处理方式都不一样的也没关系,只要往rator_handler里添加新的处理方式就行了。 编辑:添加了infix的排版方式。

import functools

def to_sexpr(ast):
    if isinstance(ast, (int, basestring)):
        return ast
    elif isinstance(ast, dict):
        rator, = ast.keys()
        children, = ast.values()

        return rator_handler[rator](rator, children)
    else:
        assert 0, 'Not a valid ast: %r' % ast

def handle_binary(rator, children):
    lhs, rhs = map(singleton_dict, children.items())
    return (rator, to_sexpr(lhs), to_sexpr(rhs))

def singleton_dict((k, v)):
    return {k: v}

def handle_multiary_join_or(rator, children):
    lhs, = children.keys()
    rhss, = children.values()
    exprs = [(rator, lhs, to_sexpr(rhs)) for rhs in rhss]
    return functools.reduce(mk_binary_or, exprs)

def mk_binary_or(a, b):
    return ('or', a, b)

# Add other operator handlers here
rator_handler = {
    'or': handle_binary,
    '>': handle_multiary_join_or,
    '=': handle_multiary_join_or
}

def ppr_sexpr(e):
    if isinstance(e, (int, basestring)):
        return str(e)
    elif isinstance(e, tuple):
        return '(%s)' % ' '.join(map(ppr_sexpr, e))
    else:
        assert 0, 'Not a valid expr: %r' % e

def ppr_infix(e):
    if isinstance(e, (int, basestring)):
        return str(e)
    elif isinstance(e, tuple):
        rator = e[0]
        if rator == 'or':
            lhs, rhs = e[1:]
            return '%s %s %s' % (ppr_infix(lhs), rator, ppr_infix(rhs))
        elif rator in ('>', '='):
            lhs, rhs = e[1:]
            return '%s %s %s' % (ppr_infix(lhs), rator, ppr_infix(rhs))
        else:
            assert 0, 'Dont know how to ppr_infix: %r' % e
    else:
        assert 0, 'Not a valid expr: %r' % e

def test():
    data = {
        'or': {
            '=': {
                'name': ['aaa', 'bbb']
            },
            '>': {
                'age': [1, 2, 3]
            }
        }
    }

    e = to_sexpr(data)
    print(ppr_infix(e))
    # => name = aaa or name = bbb or age > 1 or age > 2 or age > 3

if __name__ == '__main__':
    test()
新手上路,请多包涵

可以参考一下json格式解析的代码

这个还算能用。

def flatten(nested):
    for k,v in nested.items():
        try:
            yield [(' '+k+' ').join(x) for x in flatten(v)]
        except AttributeError: // list 没有 items 方法
            for i in v:
                yield [k,i]

data={
    "or":{
        "like":{
            "name": ["aaa", "bbb"]
        }
    }
}

print list(flatten(data))
>>>[['name like aaa or name like bbb']]

超过三层嵌套貌似就不行了?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题