使用Python中的递归函数更改嵌套json文件中的值

时间:2018-04-09 08:36:53

标签: python json recursion nested

您好我想创建一个递归函数,它可以使用嵌套json文件制作的字典,并将json文件中某个属性(属性权重)的所有值乘以10。

我知道这可以通过其他方式解决(例如正则表达式),但我这样做是为了提高我编写递归函数的能力,所以我想找到一个递归解决方案。

示例输入json文件:

    {
      "name": "Entire genepool",
      "children": [{
        "name": "child1",
        "weight": 80,
        "children": [{
          "name": "childAA",
          "weight": 100,
          "children": [{
            "name": "childCC",
            "weight": 60,
            "children": []
          }, {
            "name": "grandchild",
            "weight": 40,
            "children": []
          }]
        }]
      }, {
        "name": "childb",
        "weight": 20,
        "children": []
      }]
    }

这是我到目前为止所做的(Python 2.7),它不起作用,它返回一个空列表,我添加了一个print语句来可视化输入字典在递归中的变化:

    def recur(dict1):
        print dict1
        print 
        """
        it multiplies * 10 weight attribute in nested json file
        """
        # reduce on step closer to solution
        if not isinstance(dict1, list):
            for key , content in dict1.iteritems():
                if key == "weight":
                    dict1["weight"] = dict1["weight"]*10 
            for key , content in dict1.iteritems():
                if key == "children":
                    simpler_dict = dict1["children"]
                    return  recur(simpler_dict)
        else:
            if len(dict1) < 1:
                return dict1
            else:
                for sub_dict in dict1:
                    for key , content in sub_dict.iteritems():
                        if key == "weight":
                            sub_dict["weight"] = sub_dict["weight"]*10 
                    for key , content in sub_dict.iteritems():
                        if key == "children":
                            simpler_dict2 = sub_dict["children"]
                            return  recur(simpler_dict2)

打开文件将其转换为字典并调用函数

with open("tree_rec.json", "r") as f:
    tree_dic = json.load(f)
recur(tree_dic) 

每个递归的输入

  {u'name': u'Entire genepool', u'children': [{u'name': u'child1', u'weight': 80, u'children': [{u'name': u'childAA', u'weight': 100, u'children': [{u'name': u'childCC', u'weight': 60, u'children': []}, {u'name': u'grandchild', u'weight': 40, u'children': []}]}]}, {u'name': u'childb', u'weight': 20, u'children': []}]}

  [{u'name': u'child1', u'weight': 80, u'children': [{u'name': u'childAA', u'weight': 100, u'children': [{u'name': u'childCC', u'weight': 60, u'children': []}, {u'name': u'grandchild', u'weight': 40, u'children': []}]}]}, {u'name': u'childb', u'weight': 20, u'children': []}]

  [{u'name': u'childAA', u'weight': 100, u'children': [{u'name': u'childCC', u'weight': 60, u'children': []}, {u'name': u'grandchild', u'weight': 40, u'children': []}]}]

  [{u'name': u'childCC', u'weight': 60, u'children': []}, {u'name': u'grandchild', u'weight': 40, u'children': []}]

  []

它返回一个空列表:[]

2 个答案:

答案 0 :(得分:0)

我认为你正在寻找的递归可以这样实现:

def main_caller(json_file):
    if "weight" in json_file:
        json_file["weight"] *= 10
    if "children" in json_file and json_file["children"]:
        for child_index , children in enumerate(json_file["children"]):
            json_file["children"][child_index] = main_caller(children)
    return json_file

答案 1 :(得分:0)

你只需要在dicts中查找“weight&#39; -keys”并迭代所有列表,你的recur函数可以简单得多:

x =  {"name": "Entire genepool", ...}

def recur(data):
    if isinstance(data, dict):
        for key, value in data.items():
            if key == 'weight':
              data[key] = value*10
            elif isinstance(value, list):
              for i, item in enumerate(value):
                value[i] = recur(item)
        return data

result = recur(x)

结果:

{
    "children": [
        {
            "children": [
                {
                    "children": [
                        {
                            "children": [],
                            "name": "childCC",
                            "weight": 600
                        },
                        {
                            "children": [],
                            "name": "grandchild",
                            "weight": 400
                        }
                    ],
                    "name": "childAA",
                    "weight": 1000
                }
            ],
            "name": "child1",
            "weight": 800
        },
        {
            "children": [],
            "name": "childb",
            "weight": 200
        }
    ],
    "name": "Entire genepool"
}