【问题标题】:changing values in nested json file with a recursive function in Python在 Python 中使用递归函数更改嵌套 json 文件中的值
【发布时间】:2018-09-18 14:28:15
【问题描述】:

您好,我想创建一个递归函数,该函数可以获取由嵌套 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),它不起作用,它返回一个空列表,我添加了一个打印语句来可视化输入字典如何通过递归进行更改:

    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': []}]

  []

它返回一个空列表:[]

【问题讨论】:

  • “不起作用”是对问题最没有用的描述。请解释它“不起作用”的方式(如果您遇到异常,请发布确切的错误消息和完整的回溯。
  • 哦,是的:你甚至没有展示你是如何调用那个函数的......
  • 添加print 语句来跟踪您的函数的执行或在步进调试器中运行它(docs.python.org/2/library/pdb.html),问题应该非常明显。提示:编写你的函数,使其要么改变它的输入并且不返回任何内容,要么(排他的“或”)创建一个新的(修改后的)字典并返回它,但不要试图混合两者。

标签: python json recursion nested


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    您只需要在 dicts 中查找“权重”键并遍历所有列表,您的 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"
    }
    

    【讨论】:

      猜你喜欢
      • 2020-01-15
      • 1970-01-01
      • 2019-09-06
      • 2017-02-16
      • 2022-01-19
      • 1970-01-01
      • 1970-01-01
      • 2021-12-04
      • 2021-10-23
      相关资源
      最近更新 更多