Cómo modificar la clave de un Json nested.

Estoy intentando actualizar las claves de un objeto JSON que se parece a esto:

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

Actualmente estoy actualizando manualmente cada clave como sigue

 ##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'] 

Tiene que haber una mejor manera de hacerlo ya que me encuentro teniendo que actualizar varias claves sobre los resultados. Por ejemplo, también quiero actualizar la clave “número” a “assis_ref”.

Sé cómo actualizar una clave si el archivo json es “simple”: es decir, si pudiera hacer esto:

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

sin embargo, ‘stats’ y ‘details’ requieren [0] junto a él, que asumo que es el índice del elemento que estoy tratando de ir a continuación.

Puede ser doloroso navegar y modificar objetos profundamente nesteds derivados de objetos JSON. En Funciones que ayudan a comprender la estructura json (dict), publiqué un código que le permite navegar por dichos objetos. Por favor lea la explicación en esa respuesta. En esta respuesta, mostraré cómo puede usar ese código para modificar las claves del diccionario en tales objetos.

Brevemente, find_key es un generador recursivo que encontrará todas las claves con un nombre dado. Puede usar la next función para obtener el primer nombre (o el único) que coincida. O llame a find_key en un bucle for si necesita trabajar con varias teclas que tienen el mismo nombre.

Cada valor find_key por find_key es una lista de las claves de dict y los índices de la lista deben alcanzar la clave deseada.

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

salida

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