Python read JSON file and modify
Set item using data['id'] = ...
.
import json
with open('data.json', 'r+') as f:
data = json.load(f)
data['id'] = 134 # <--- add `id` value.
f.seek(0) # <--- should reset file position to the beginning.
json.dump(data, f, indent=4)
f.truncate() # remove remaining part
How to update a JSON file by using Python?
You did not save the changed data at all. You have to first load, then modify, and only then save. It is not possible to modify JSON files in-place.
with open('my_file.json', 'r') as f:
json_data = json.load(f)
json_data['b'] = "9"
with open('my_file.json', 'w') as f:
f.write(json.dumps(json_data))
You may also do this:
with open('my_file.json', 'r+') as f:
json_data = json.load(f)
json_data['b'] = "9"
f.seek(0)
f.write(json.dumps(json_data))
f.truncate()
If you want to make it safe, you first write the new data into a temporary file in the same folder, and then rename the temporary file onto the original file. That way you will not lose any data even if something happens in between.
If you come to think of that, JSON data is very difficult to change in-place, as the data length is not fixed, and the changes may be quite significant.
Working on .json files (read/write/change) on-the-fly with Python
I would recommend you to just use the json library. Read the file once and do occasionally a save, let's say every five minutes.
Maybe you want to create a new class in a singleton pattern. This will ensure that you have one object that holds the current up-to-date information and only this object can update the file.
Here is a quick sketch on how this class may look like:
# SaveFileHandler.py
import json
class _SaveFileHandler:
def __init__(self):
self._data = {}
self._path = ""
def read(self, path):
self._path = path
with open(path) as file:
self._data = json.load(file)
def write(self):
with open(self._path) as file:
json.dump(self._data, file)
# now for every value you want data to have do the following
# it allows you to check the value for errors and makes the usage more readable
@property
def key(self):
return self._data["key"]
@key.setter
def key(self, value):
self._data["key"] = value
# the is the only object you will ever use
save_file = _SaveFileHandler()
You can also read the save file directly in the init, this will make sure your data is always available.
How to modify a JSON file in a script?
import json
with open(path_to_json_file) as f:
data = f.read()
d = json.loads(data)
d["browser"]["enabled_labs_experiments"] = ["ssl-version-max@2"]
with open(path_to_json_file, 'w') as f:
f.write(json.dumps(d))
How to modify the multiple values in the JSON file using python
The code works as expected if you have resolved the variable name difference.
Further, I would also suggest to open the file using context manager with
so that it gets closed automagically when the with
block is exited.
import json, os
with open(".\example.json", 'r') as f:
data = json.load(f)
for feature in data['images']:
feature['file_name'] = os.path.basename(feature["file_name"])
print(data)
Output:
Data in json
file:
{'images': [{'id': 1, 'file_name': 'Folder1/Folder2/Folder3/Folder4/1110.jpg', 'height': 3024, 'width': 4032}, {'id': 2, 'file_name': 'Folder1/Folder2/Folder3/Folder4/1111.jpg', 'height': 3024, 'width': 4032}, {'id': 3, 'file_name': 'Folder1/Folder2/Folder3/Folder4/1112.jpg', 'height': 3024, 'width': 4032}]}
Formatted data:
{'images': [{'id': 1, 'file_name': '1110.jpg', 'height': 3024, 'width': 4032}, {'id': 2, 'file_name': '1111.jpg', 'height': 3024, 'width': 4032}, {'id': 3, 'file_name': '1112.jpg', 'height': 3024, 'width': 4032}]}
How to open and edit an incorrect json file?
The file isn't JSON (the filename is incorrect); instead, it's composed of valid Python literals. There's no reason to try to transform it to JSON. Don't do that; instead, just tell Python to parse it as-is.
#!/usr/bin/env python3
import ast, json
results = [ ast.literal_eval(line) for line in open('qa_Appliances.json') ]
print(json.dumps(results))
...properly gives you a list named results
with all your lines in it, and (for demonstration purposes) dumps it to stdout as JSON.
Update a JSON file with Python and keep the original format
Try json.dumps(json_obj, indent=4)
Example:
import json
status_wifi = "ok"
with open("config_wifi.json", "r") as jsonFile:
data = json.load(jsonFile)
data['wifi_session']['status'] = status_wifi
with open("config_wifi.json", "w") as jsonFile:
json.dump(json.dumps(data, indent=4), jsonFile)
The indent is the number of spaces for a tab.
If you set this parameter, the JSON will be formatted.
You can read more about it here.
How to modify JSON in python
Some errors in your code:
- You don't need to re-iterate over the
annotations
again and again for every item inimages
, remove it out of the loop - You don't need to update all the keys of
element
for every item inannotations
. Remove it out of the loop. - The usage of all other auxiliary containers such as
listElements
,listAnnotations
, andkk
are not needed. You can update the targetelements
directly if you refactored your code.
With the points above, consider this approach.
- First, get all the annotations grouped by image_id
- Then, iterate each image. For each image, just get the target annotation from the previous step. Construct the target dictionary and append to the result.
from collections import defaultdict
elements = []
annotation = defaultdict(list)
dataset_dicts = {"categories": [{"supercategory": "", "id": 0, "name": "Negative", "tiles": 2489, "bboxes": 5527, "className": "Negative"}, {"supercategory": "", "id": 1, "name": "Positive", "tiles": 5227, "bboxes": 15362, "className": "Positive"}], "images": [{"id": 224, "file_name": "img1.jpg", "height": 512, "width": 512}, {"id": 225, "file_name": "img2.jpg", "height": 512, "width": 512}], "annotations": [{"id": 716, "image_id": 224, "category_id": 0, "iscrowd": 0, "area": 2856.0, "bbox": [298, 18, 56, 51]}, {"id": 715, "image_id": 224, "category_id": 0, "iscrowd": 0, "area": 4096.0, "bbox": [185, 68, 64, 64]}, {"id": 714, "image_id": 224, "category_id": 0, "iscrowd": 0, "area": 2744.0, "bbox": [354, 10, 56, 49]}, {"id": 717, "image_id": 225, "category_id": 0, "iscrowd": 0, "area": 4096.0, "bbox": [374, 397, 64, 64]}]}
for item in dataset_dicts['annotations']:
annotation[item["image_id"]].append(
{
"bbox": list(map(float, item["bbox"])), # Or just item["bbox"].copy() if you don't intend it to be float
"bbox_mode": 1,
"category_id": str(item["category_id"]), # Or just item["category_id"] if you don't intend it to be string
}
)
for item in dataset_dicts["images"]:
elements.append(
{
"image_id": item["id"],
"file_name": item["file_name"],
"height": item["height"],
"width": item["width"],
"annotations": annotation[item["id"]],
}
)
print(elements)
Output
[
{
"image_id": 224,
"file_name": "img1.jpg",
"height": 512,
"width": 512,
"annotations": [
{
"bbox": [
298.0,
18.0,
56.0,
51.0
],
"bbox_mode": 1,
"category_id": "0"
},
{
"bbox": [
185.0,
68.0,
64.0,
64.0
],
"bbox_mode": 1,
"category_id": "0"
},
{
"bbox": [
354.0,
10.0,
56.0,
49.0
],
"bbox_mode": 1,
"category_id": "0"
}
]
},
{
"image_id": 225,
"file_name": "img2.jpg",
"height": 512,
"width": 512,
"annotations": [
{
"bbox": [
374.0,
397.0,
64.0,
64.0
],
"bbox_mode": 1,
"category_id": "0"
}
]
}
]
Related Topics
Subprocess Readline Hangs Waiting for Eof
Socket.Shutdown VS Socket.Close
Python - Rolling Functions for Groupby Object
How to Change a Module Variable from Another Module
How Can This Function Be Rewritten to Implement Ordereddict
Can Existing Virtualenv Be Upgraded Gracefully
Converting an Rgb Color Tuple to a Hexidecimal String
Modules Are Installed Using Pip on Osx But Not Found When Importing
Opencv Error: (-215)Size.Width>0 && Size.Height>0 in Function Imshow
Pythonic Way to Check If a File Exists
Rename Specific Column(S) in Pandas
Comprehension for Flattening a Sequence of Sequences
Explicitly Select Items from a List or Tuple
Comparing Python Dictionaries and Nested Dictionaries
How to Extract an Arbitrary Line of Values from a Numpy Array