如何修改嵌套Json的键 [英] how to modify the key of a nested Json

查看:132
本文介绍了如何修改嵌套Json的键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试更新如下所示的JSON对象的键:

I am trying to update the keys of a JSON object which looks like this:

results = 
 {  
   'Game':12345,
   'stats':[  
      {  
         'detail':[  
            {  
               'goals':4,
               'refs':{  
                  'number':0

我目前正在按照以下说明手动更新每个密钥

I am currently manually updating each key as follow

##update Game to newValue
results['newValue'] = results['Game']
    del results['Game']

## update nested key "goals" to "goals_against"
results['stats'][0]['detail'][0]['goals_against'] = results['stats'][0]['detail'][0]['goals']
    del results['stats'][0]['detail'][0]['goals']

必须找到一种更好的方法,因为我发现自己必须更新结果的多个键.例如,我还想将数字"键更新为"assis_ref".

there has to be a better way to do as I am finding myself having to update multiple keys on results. For example, I also want to update the "number" key to "assis_ref".

如果json文件是"simple",我知道如何更新密钥:即如果我可以做到这一点:

I know how to update a key if is the json file is "simple": ie if i could do this:

result['stats']['details']['refs']

但是,"stats"和"details"在其旁边需要[0],我认为这是我接下来要尝试的元素的索引.

however, 'stats' and 'details' require [0] next to it which i assume is the index of the element i am trying to go next.

推荐答案

导航和修改从JSON对象派生的深层嵌套对象可能很麻烦.在有助于理解json(dict)结构的功能中,我发布了允许您导航此类对象的代码.请阅读该答案中的说明.在这个答案中,我将展示如何使用该代码来修改此类对象中的字典键.

It can be painful navigating and modify deeply nested objects derived from JSON objects. In Functions that help to understand json(dict) structure I posted code that allows you to navigate such objects. Please read the explanation in that answer. In this answer, I'll show how you can use that code to modify the dictionary keys in such objects.

简而言之,find_key是一个递归生成器,它将查找具有给定名称的所有键.您可以使用next函数获取第一个(或唯一)匹配名称.或者,如果需要使用多个具有相同名称的键,请在for循环中调用find_key.

Briefly, find_key is a recursive generator that will find all the keys with a given name. You can use the next function to get the first (or only) matching name. Or call find_key in a for loop if you need to work with multiple keys that have the same name.

find_key产生的每个值都是dict键的列表,并且列表索引需要到达所需的键.

Each value yielded by find_key is a list of the dict keys and list indices need to reach the desired key.

from json import dumps

def find_key(obj, key):
    if isinstance(obj, dict):
        yield from iter_dict(obj, key, [])
    elif isinstance(obj, list):
        yield from iter_list(obj, key, [])

def iter_dict(d, key, indices):
    for k, v in d.items():
        if k == key:
            yield indices + [k], v
        if isinstance(v, dict):
            yield from iter_dict(v, key, indices + [k])
        elif isinstance(v, list):
            yield from iter_list(v, key, indices + [k])

def iter_list(seq, key, indices):
    for k, v in enumerate(seq):
        if isinstance(v, dict):
            yield from iter_dict(v, key, indices + [k])
        elif isinstance(v, list):
            yield from iter_list(v, key, indices + [k])


results = {
    "Game": 12345,
    "stats": [
        {
            "detail": [
                {
                    "goals": 4,
                    "refs": {
                        "number": 0
                    }
                }
            ]
        }
    ]
}

# Change oldkey to newkey      
oldkey, newkey = 'goals', 'goals_against'
# Find the first occurrence of the oldkey
seq, val = next(find_key(results, oldkey))
print('seq:', seq, 'val:', val)

# Get the object that contains the oldkey 
obj = results
for k in seq[:-1]:
    obj = obj[k]

# Change the key
obj[newkey] = obj.pop(oldkey)

print(dumps(results, indent=4))

输出

seq: ['stats', 0, 'detail', 0, 'goals'] val: 4
{
    "Game": 12345,
    "stats": [
        {
            "detail": [
                {
                    "refs": {
                        "number": 0
                    },
                    "goals_against": 4
                }
            ]
        }
    ]
}

这篇关于如何修改嵌套Json的键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆