0

I'm newbie in Python and struggling with function that changes nested Json values. Now I've this:

def change_json(key, new_value, json_body):
    file = open(json_body, "r")
    json_object = json.load(file)
    file.close()
    json_object[key] = new_value
    file = open(json_body, "w")
    json.dump(json_object, file)
    file.close()

It works perfect if json has simple structure, like this:

{
    "A": "test"
}

But I don't know how to point nested fields, like this:

{
    "data":{
        "A": "test"
    } 
}

I'd like smth like this:

change_json(["data"]["A"], "test2", xyz.json)

In next step I'm going to implement this function with lists - I would pass list of keys and list of values which has same amount of variables.

Thanks for help :) Happy Xmas guys

Lezakk
  • 21
  • 2
  • Look at what `jsonpath` can do for you: https://pypi.org/project/jsonpath-ng/ - it's been built precisely for this kind of task. – Tomalak Dec 23 '20 at 11:07
  • well if you are not aware with the json structure as it can be nested, so it is better to use [BFS](https://en.wikipedia.org/wiki/Breadth-first_search) or [DFS](https://en.wikipedia.org/wiki/Depth-first_search) to get the result – sahasrara62 Dec 23 '20 at 11:09
  • JSON dictionaries by definition do not have an order. – tripleee Dec 23 '20 at 11:18
  • @Tomalak so I can find value by given path, but i can't replace it with new value. Am I missing something? – Lezakk Dec 23 '20 at 12:12
  • @sahasrara62 I'll read about this algorithms, thanks. Also I thought it's common problem, and there is lots of ready-to-use solutions. – Lezakk Dec 23 '20 at 12:15
  • @Lezakk Yes. You give the path and the new value to the function, and the function uses jsonpath to find the target and do the replacement. That's pretty much exactly the same setup as you have now, except that currently your "path" is limited to a single key. – Tomalak Dec 23 '20 at 12:15
  • @tripleee yeah, but what it has to my problem? – Lezakk Dec 23 '20 at 12:16
  • @Tomalak I probably make some stupid mistake rn, but here is what I want to do: jsonpath_expression = parse(json_path) jsonpath_expression.find(json_object) = new_value But of course it wont works because it's returns value of pointed field. Shall I iterate through json to get to this field? I'm confused – Lezakk Dec 23 '20 at 12:27
  • @Lezakk See here https://stackoverflow.com/questions/59057672/update-json-nodes-in-python-using-jsonpath – Tomalak Dec 23 '20 at 12:38
  • I assumed you were unhappy that the JSON keys in the output file are potentially reordered; if that's not what you are trying to ask about, maybe [edit] to clarify where exactly you are stuck. Rereading, I guess the first comment it the solution you should be looking at. – tripleee Dec 23 '20 at 12:56
  • 1
    @Tomalak bro U R AWESOME! That's exactly what i was looking for! Hope Santa will give U lots of DDR4! Thanks for help ;) – Lezakk Dec 23 '20 at 13:00
  • @Lezakk If you want to give something back, post the working function below as an answer of your own. This might help someone in the future, and it allows you to close the thread (posting and accepting your own solutions is perfectly fine on SO). – Tomalak Dec 23 '20 at 13:08

0 Answers0