更新嵌套JSON文件中的深层键

时间:2016-08-22 03:16:15

标签: python json

我有一个json文件,如下所示:

{
    "email": "abctest@xxx.com", 
    "firstName": "name01", 
    "surname": "Optional"
    "layer01": {
        "key1": "value1", 
        "key2": "value2", 
        "key3": "value3", 
        "key4": "value4", 
        "layer02": {
            "key1": "value1", 
            "key2": "value2"
        }, 
        "layer03": [
            {
                "inner_key01": "inner value01"
            }, 
            {
                "inner_key02": "inner_value02"
            }
        ]
    }, 
    "surname": "Required only$uid"
}

我希望更新请求为:

{
                "email": "XYZTEST@gmail.com",
                "firstName": "firstName",
                "layer01.key3": "newvalue03",
                "layer01.layer02.key1": "newvalue01"
            },

使用"."

分隔更深的键

我正在使用python2.7。任何人都可以就此提出建议..我真的被困在这个!!

这就是我的工作:

def updateTemplate(self,templatename, data):
    template= self.getTemplatedata(templatename) # gets the python object with the data from original file

    for ref in data:
        k= ref
        keys= ref.split(".")
        temp= template
        if len(keys)>1:
            temp= template[keys[0]]
            for i in range(1,lens(keys)-1):
                print keys[i]
                if type(temp) is dict:
                    temp =temp[keys[i]]



            temp[keys[len(keys)-1]]= data[k]
            print temp

            template.update(temp)        
        else:
            template[k]= data[k]   
    print template  

update在模板对象中添加了一个全新的键。我需要将最后一个temp中的密钥更新为模板对象

模板对象显示为:

{   u'email': u'abctest@xxx.com',
    u'firstName': u'Valid AU$uid',
    u'key1': u'value1',
    u'key2': u'value2',
    u'key3': u'value03',
    u'key4': u'value4',
    u'layer01': {   u'key1': u'value1',
                    u'key2': u'value2',
                    u'key3': u'value03',
                    u'key4': u'value4',
                    u'layer02': {   u'key1': u'value01', u'key2': u'value2'},
                    u'layer03': [   {   u'inner_key01': u'inner value01'},
                                    {   u'inner_key02': u'inner_value02'}]},
    u'layer02': {   u'key1': u'value01', u'key2': u'value2'},
    u'layer03': [   {   u'inner_key01': u'inner value01'},
                    {   u'inner_key02': u'inner_value02'}],
    u'surname': u'Required only$uid'}

2 个答案:

答案 0 :(得分:0)

尽管我想帮助你,但我发现你的代码令人困惑,但我会尽我所能。在这里

对于初学者来说,temp= template你的意思是temp= copy.deepcopy(template)吗?请记住import copy Reference

我得到的模板是一本字典,但你希望通过引用templatetemp来实现什么,调整temp然后添加

  

template.update(temp)

temptemplate实际上temp是对template的引用?

我们如何废弃代码并重新开始。

即。输入是

{
    "email": "XYZTEST@gmail.com",
    "firstName": "firstName",
    "layer01.key3": "newvalue03",
    "layer01.layer02.key1": "newvalue01"
}

现有数据是:

{
    "email": "abctest@xxx.com", 
    "firstName": "name01", 
    "surname": "Optional"
    "layer01": {
        "key1": "value1", 
        "key2": "value2", 
        "key3": "value3", 
        "key4": "value4", 
        "layer02": {
            "key1": "value1", 
            "key2": "value2"
        }, 
        "layer03": [
            {
                "inner_key01": "inner value01"
            }, 
            {
                "inner_key02": "inner_value02"
            }
        ]
    }, 
    "surname": "Required only$uid"
}

预期产出:

{
    "email": "XYZTEST@gmail.com", 
    "firstName": "firstName", 
    "surname": "Optional"
    "layer01": {
        "key1": "value1", 
        "key2": "value2", 
        "key3": "newvalue03", 
        "key4": "value4", 
        "layer02": {
            "key1": "newvalue01", 
            "key2": "value2"
        }, 
        "layer03": [
            {
                "inner_key01": "inner value01"
            }, 
            {
                "inner_key02": "inner_value02"
            }
        ]
    }, 
    "surname": "Required only$uid"
}

请确认这是否是您期望的结果,所以我可以帮助您进行头脑风暴。

答案 1 :(得分:0)

你的算法非常接近,但其中有一些东西使得不必要地复杂化了。这使得很容易错过导致问题的关键线:

template.update(temp) 

temp是模板的子项最多字典,但是在这里您将原始模板设置为包含所有它的孩子。评论这一行,它应该有效。

我清理了一些使这条线更容易找到的东西:

  • 不要对keys列表中只有一个元素的情况进行硬编码。循环可以处理它。
  • 在Python中,keys[len(keys)-1]keys[-1]有一个很好的简写。请参阅Negative index to Python list
  • 而不是使用枚举并检查temp的类型是否是dict,而不是在最后一个键上循环(这可能会改变其他输入的行为)
  • 使用pprint。它可以打印列表和词典等内容。

放在一起,简化版看起来像这样:

import pprint

def updateTemplate(self, templatename, data):
    template = self.getTemplatedata(templatename) # gets the python object with the data from original file

    for ref in data:
        keys = ref.split(".")
        temp = template
        for key_part in keys[:-1]:
            temp = temp[key_part]
        temp[keys[-1]] = data[ref] # Because dictionaries are mutable, this updates template too

    pprint.pprint(template)  

希望这有帮助。