2016-10-24 114 views
0

我有一個Python AST解析器,轉換像1==1 or 2==2 or 3==3表達到這個字典:Python的修改字典遞歸

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

這是再轉換爲JSON併發布到和API端點,不過該API只能識別二進制or操作。所以上面粘貼的字典需要轉換(嵌套)到以下幾點:

{ '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'} 

回答

2

你可以做這樣的事情:

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)) 

如果你真的有巨大的表情,你將不得不用迭代解決方案替換遞歸。

+1

對我不起作用:'fix_ors'中的'ast'很快成爲了一個dicts列表,'ast'''''拋出了一個TypeError' – brianpck

+0

@brianpck:typo,現在就工作。 – Blender

+0

此外,還有一個'nest_ors'的調用,它應該是_nest_ors' – PepperoniPizza