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

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

 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”

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


可以参考一下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']]

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


就算每种操作符的处理方式都不一样的也没关系,只要往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()
【热门文章】
【热门文章】