Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 递归地修改字典_Python_Algorithm_Dictionary_Recursion - Fatal编程技术网

Python 递归地修改字典

Python 递归地修改字典,python,algorithm,dictionary,recursion,Python,Algorithm,Dictionary,Recursion,我创建了一个类,它应该将嵌套列表转换为字典。以下是我的意见: ['function:and', ['variable:X', 'function:>=', 'value:13'], ['variable:Y', 'function:==', 'variable:W']] 输出应为以下形式的词典: { "function": "and", "args": [ { "function": ">=", "args": [

我创建了一个类,它应该将嵌套列表转换为字典。以下是我的意见:

['function:and',
    ['variable:X', 'function:>=', 'value:13'],
    ['variable:Y', 'function:==', 'variable:W']]
输出应为以下形式的词典:

{
  "function": "and",
  "args": [
    {
      "function": ">=",
      "args": [
        {
          "variable": "X"
        },
        {
          "value": 13
        }
      ]
    },
    {
      "function": "==",
      "args": [
        {
          "variable": "Y"
        },
        {
          "variable": "W"
        }
      ]
    }
  ]
}
这是接收输入列表并应返回所需字典的类

class Tokenizer(object):
    def __init__(self, tree):
        self.tree = tree
        self.filter = {}

    def to_dict(self, triple):
        my_dict = {}
        try:
            first = triple[0]
            second = triple[1]
            third = triple[2]
        except KeyError:
            return
        if type(second) == str and type(third) == str:
            my_dict['function'] = second.split(':')[-1]
            my_dict['args'] = [
                {first.split(':')[0]: first.split(':')[1]},
                {third.split(':')[0]: third.split(':')[1]}]
        # case recursive
        if type(second) == list:
            my_dict['function'] = first.split(':')[-1]
            my_dict['args'] = [second, third]
        return my_dict

    def walk(self, args):
        left = self.to_dict(args[0])
        right = self.to_dict(args[1])
        if isinstance(left, dict):
            if 'args' in left.keys():
                left = self.walk(left['args'])
        if isinstance(right, dict):
            if 'args' in right.keys():
                right = self.walk(right['args'])
        args = [left, right]
        return args

    def run(self):
        self.filter.update(self.to_dict(self.tree))
        if 'args' in self.filter.keys():
            self.filter['args'] = self.walk(self.filter['args'])


tree = [
    'function:and',
        ['variable:X', 'function:>=', 'value:13'],
        ['variable:Y', 'function:==', 'variable:W']
    ]

import pprint
pp = pprint.PrettyPrinter(indent=4)
t = Tokenizer(tree)
t.run()
pp.pprint(t.filter)
我的递归方法
walk
没有做它应该做的事情,我完全是递归的吸盘,所以我不知道我做错了什么

我得到的结果是:

{   'args': [[None, None], [None, None]], 'function': 'and'}

对于您的特定测试用例,您根本不需要进行递归。您可以对您的通话进行评论:

def walk(self, args):
    left = self.to_dict(args[0])
    right = self.to_dict(args[1])
    #if isinstance(left, dict):
    #    if 'args' in left.keys():
    #        left = self.walk(left['args'])
    #if isinstance(right, dict):
    #    if 'args' in right.keys():
    #        right = self.walk(right['args'])
    args = [left, right]
    return args
并获得所需的输出。 如果允许在输入中使用嵌套函数,则只需进入递归:

 ['function:and',
      ['variable:X', 'function:>=', 'value:13'],
      ['function:==',
          ['variable:R', 'function:>=', 'value:1'],
          ['variable:Z', 'function:==', 'variable:K']
      ]
 ]
然后必须检查基本情况,因此只有当
args
键的值包含未处理的值时,才进入递归:

def walk(self, args):
    left = self.to_dict(args[0])
    right = self.to_dict(args[1])
    if isinstance(left, dict):
        if 'args' in left.keys() and isinstance(left['args'][0], list):
            left = self.walk(left['args'])
    if isinstance(right, dict):
        if 'args' in right.keys() and isinstance(right['args'][0], list):
            right = self.walk(right['args'])
    args = [left, right]
    return args
然后你会得到这个:

{   'args': [   {   'args': [{   'variable': 'X'}, {   'value': '13'}],
                'function': '>='},
            {   'args': [   {   'args': [   {   'variable': 'R'},
                                            {   'value': '1'}],
                                'function': '>='},
                            {   'args': [   {   'variable': 'Z'},
                                            {   'variable': 'K'}],
                                'function': '=='}],
                'function': '=='}],
'function': 'and'}

另外,如果输入列表是一个规则结构,并且在函数名字段之后始终有参数字段,则会更容易。然后,您可以将
方法大大简化为dict
方法。

对于您的特定测试用例,您根本不需要进行递归。您可以对您的通话进行评论:

def walk(self, args):
    left = self.to_dict(args[0])
    right = self.to_dict(args[1])
    #if isinstance(left, dict):
    #    if 'args' in left.keys():
    #        left = self.walk(left['args'])
    #if isinstance(right, dict):
    #    if 'args' in right.keys():
    #        right = self.walk(right['args'])
    args = [left, right]
    return args
并获得所需的输出。 如果允许在输入中使用嵌套函数,则只需进入递归:

 ['function:and',
      ['variable:X', 'function:>=', 'value:13'],
      ['function:==',
          ['variable:R', 'function:>=', 'value:1'],
          ['variable:Z', 'function:==', 'variable:K']
      ]
 ]
然后必须检查基本情况,因此只有当
args
键的值包含未处理的值时,才进入递归:

def walk(self, args):
    left = self.to_dict(args[0])
    right = self.to_dict(args[1])
    if isinstance(left, dict):
        if 'args' in left.keys() and isinstance(left['args'][0], list):
            left = self.walk(left['args'])
    if isinstance(right, dict):
        if 'args' in right.keys() and isinstance(right['args'][0], list):
            right = self.walk(right['args'])
    args = [left, right]
    return args
然后你会得到这个:

{   'args': [   {   'args': [{   'variable': 'X'}, {   'value': '13'}],
                'function': '>='},
            {   'args': [   {   'args': [   {   'variable': 'R'},
                                            {   'value': '1'}],
                                'function': '>='},
                            {   'args': [   {   'variable': 'Z'},
                                            {   'variable': 'K'}],
                                'function': '=='}],
                'function': '=='}],
'function': 'and'}

另外,如果输入列表是一个规则结构,并且在函数名字段之后始终有参数字段,则会更容易。然后,您可以将
方法大大简化为_dict
方法。

我的方法没有做它应该做的事情,所以它在做什么?@JohnGordon:编辑以添加输出,谢谢!可能是@das-g的一个例子:修复了,谢谢。帕斯特不是你的朋友也许有了这个“开始”,你会更容易找到方向。我的方法没有做它应该做的,那么它在做什么?@JohnGordon:编辑以添加输出,谢谢!可能是@das-g的一个例子:修复了,谢谢。帕斯特不是你的朋友也许有了这个“开始”,你会更容易找到路。