how to modify the key of a nested Json

后端 未结 1 1335
猫巷女王i
猫巷女王i 2021-01-28 02:05

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

results = 
 {  
   \'Game\':12345,
   \'stats\':[  
      {  
         \'detail\':[  
             


        
相关标签:
1条回答
  • 2021-01-28 02:51

    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.

    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.

    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))
    

    output

    seq: ['stats', 0, 'detail', 0, 'goals'] val: 4
    {
        "Game": 12345,
        "stats": [
            {
                "detail": [
                    {
                        "refs": {
                            "number": 0
                        },
                        "goals_against": 4
                    }
                ]
            }
        ]
    }
    
    0 讨论(0)
提交回复
热议问题