Python递归修改字典

Python递归修改字典,python,dictionary,recursion,Python,Dictionary,Recursion,我有一个Python AST解析器,它将1==1或2==2或3==3这样的表达式转换为以下字典: { 'args': [ {'args': [{'value': 1}, {'value': 1}], 'function': '=='}, {'args': [{'value': 2}, {'value': 2}], 'function': '=='}, {'args': [{'value': 3}, {'value': 3}], 'function'

我有一个Python AST解析器,它将
1==1或2==2或3==3这样的表达式转换为以下字典:

{ 'args': [ {'args': [{'value': 1}, {'value': 1}], 'function': '=='},
            {'args': [{'value': 2}, {'value': 2}], 'function': '=='},
            {'args': [{'value': 3}, {'value': 3}], 'function': '=='}],
  'function': 'or'}
然后将其转换为JSON并发布到和API端点,但是API只理解二进制
操作。因此,需要将上面粘贴的词典转换(嵌套)为以下内容:

{ 'args': [ { 'args': [ { 'args': [{'value': 1}, {'value': 1}],
                          'function': '=='},
                        { 'args': [{'value': 2}, {'value': 2}],
                          'function': '=='}],
              'function': 'or'},
            {'args': [{'value': 3}, {'value': 3}], 'function': '=='}],
  'function': 'or'}
从Python AST执行此操作是不可能的,因为
BoolOp
有3个元素,所以我认为最好递归执行。然而,我无法想象一种正确的方法来实现这一点,即以递归的方式迭代字典

编辑:

字典可以嵌套得很深,如:

{ 'args': [ {'args': [{'value': 1}, {'value': 1}], 'function': '=='},
            {'args': [{'value': 2}, {'value': 2}], 'function': '=='},
            { 'args': [ { 'args': [{'value': 3}, {'value': 3}],
                          'function': '=='},
                        { 'args': [{'value': 4}, {'value': 4}],
                          'function': '=='},
                        { 'args': [{'value': 5}, {'value': 5}],
                          'function': '=='}],
              'function': 'or'}],
  'function': 'and'}

你可以这样做:

def _nest_ors(args):
    assert len(args) >= 2

    if len(args) == 2:
        return {
            'function': 'or',
            'args': args
        }

    return {
        'function': 'or',
        'args': [args[0], _nest_ors(args[1:])]
    }


def fix_ors(ast):
    assert ast['function'] == 'or'

    return _nest_ors(ast['args'])


expression = {'args': [{'args': [{'value': 1}, {'value': 1}], 'function': '=='},
                       {'args': [{'value': 2}, {'value': 2}], 'function': '=='},
                       {'args': [{'value': 3}, {'value': 3}], 'function': '=='}],
              'function': 'or'}

print(fix_ors(expression))

如果您有非常大的表达式,则必须用迭代解决方案替换递归。

您可以执行以下操作:

def _nest_ors(args):
    assert len(args) >= 2

    if len(args) == 2:
        return {
            'function': 'or',
            'args': args
        }

    return {
        'function': 'or',
        'args': [args[0], _nest_ors(args[1:])]
    }


def fix_ors(ast):
    assert ast['function'] == 'or'

    return _nest_ors(ast['args'])


expression = {'args': [{'args': [{'value': 1}, {'value': 1}], 'function': '=='},
                       {'args': [{'value': 2}, {'value': 2}], 'function': '=='},
                       {'args': [{'value': 3}, {'value': 3}], 'function': '=='}],
              'function': 'or'}

print(fix_ors(expression))

如果你有非常大的表达式,你必须用迭代的解决方案来代替递归。

对我不起作用:
fix\u or
中的
ast
很快就会变成一个dict列表,
ast['function']
还会抛出一个
TypeError
,有一个对
nest\u ors
的调用,它应该是
\u nest\u ors
@Blender:谢谢,仍然返回一个额外的'or',外部的'or',它不接收2个参数。@pepper:Fixed@Blender:接受您的回答,但是您能否建议如何解决递归问题,例如我在编辑中添加的字典?一些
arg
可能大小为2,但其中一个arg内部也可能存在故障元素。这对我不起作用:
fix\u ors
中的
ast
很快就会变成一个dict列表,
ast['function']
还会抛出一个
TypeError
,有一个对
nest\u ors
的调用,它应该是
\u nest\u ors
@Blender:谢谢,仍然返回一个额外的'or',外部的'or',它不接收2个参数。@pepper:Fixed@Blender:接受您的回答,但是您能否建议如何解决递归问题,例如我在编辑中添加的字典?一些
arg
的大小可能为2,但其中一个arg内部也可能存在故障元素。