Python递归修改字典
我有一个Python AST解析器,它将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'
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内部也可能存在故障元素。