2

I have a JSON file named 'students.json' which is as follows:-

{
    "students": {
        "1":{
            "name": "Ricky",
            "marks": {
                "science": "90",
                "english": "50"
            }
        },
        "2":{
            "name": "Brad",
            "marks": {
                "science": "80",
                "english": "75"
            }
        }
    }
}

I want to update Brad's english marks to 85. All I have is the JSON file, a list of path to marks, and updated marks.

updated_marks = "85"
path_to_marks = ["students", "2", "marks", "english"]

I want to do something like this,

import json

updated_marks = "85"
path_to_marks = ["students", "2", "marks", "english"]

with open('students.json', 'r+') as f:
    json_data = json.load(f)
    value = json_data

    #TODO: code to update marks
    
    f.seek(0)
    f.write(json.dumps(json_data))
    f.truncate()
1
  • look at this answer, it's pretty much what you are trying to do Commented Dec 16, 2021 at 10:44

3 Answers 3

3
def update(json, path, new_value):
    obj_ptr = json
    for key in path:
        if key == path[-1]:
            obj_ptr[key] = new_value
        obj_ptr = obj_ptr[key]

Call it from your code like this:

update(json_data, path_to_marks, updated_marks)
Sign up to request clarification or add additional context in comments.

Comments

1

Since you use json.load to load the file back into a Python object via the default conversion table, you should get a dictonary in your case.

So you should be able to edit the data normally like in a dict, in your case:

json_data["students"]["2"]["marks"]["english"] = updated_marks

EDIT:

Since you want to make the call based on the path_to_english_marks list, you can do something like mentioned here from jjp.

from functools import reduce
from operator import getitem

def set_nested_item(dataDict, mapList, val):
    """Set item in nested dictionary"""
    reduce(getitem, mapList[:-1], dataDict)[mapList[-1]] = val
    return dataDict

key_lst = ["key1", "key2", "key3"]
value = "my_value"
d = {"key1": {"key2": {"key3": "some_value"}}}

d = set_nested_item(d, key_lst, value)

print(d)
# {'key1': {'key2': {'key3': 'my_value'}}}

2 Comments

Values are not fixed in the list, they can change. For example, I can receive- ["students", "3", "marks", "science"]. In this case, I have to update the science marks of 3rd student.
Ok, means you want to manipulate a value based on the list path_to_english_marks. If the structure makes sense, we leave aside for now. You actually only have to take the list as keys for the request.
-1

Save it directly

data['students']['2']['marks']['english'] = marks

1 Comment

Hi, this would set it, but can you include the save part as well?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.