How to Dump a Dict to a JSON File

Saving json file by dumping dictionary in a for loop, leading to malformed json

JSON may only have one root element. This root element can be [], {} or most other datatypes.

In your file, however, you get multiple root elements:

{...}{...}

This isn't valid JSON, and the error Extra data refers to the second {}, where valid JSON would end instead.

You can write multiple dicts to a JSON string, but you need to wrap them in an array:

[{...},{...}]


But now off to how I would fix your code. First, I rewrote what you posted, because your code was rather pseudo-code and didn't run directly.

import json

inputs = [(["scientific name", "common names", "colors"],
["somename1", ["name11", "name12"], ["color11", "color12"]]),
(["scientific name", "common names", "colors"],
["somename2", ["name21", "name22"], ["color21", "color22"]])]

for keys, values in inputs:
d = dict(zip(keys, values))
with open("file.json", 'a') as j:
json.dump(d, j)

with open("file.json", 'r') as j:
print(json.load(j))

As you correctly realized, this code failes with

json.decoder.JSONDecodeError: Extra data: line 1 column 105 (char 104)

The way I would write it, is:

import json

inputs = [(["scientific name", "common names", "colors"],
["somename1", ["name11", "name12"], ["color11", "color12"]]),
(["scientific name", "common names", "colors"],
["somename2", ["name21", "name22"], ["color21", "color22"]])]

jsonData = list()
for keys, values in inputs:
d = dict(zip(keys, values))
jsonData.append(d)

with open("file.json", 'w') as j:
json.dump(jsonData, j)

with open("file.json", 'r') as j:
print(json.load(j))

Also, for python's json library, it is important that you write the entire json file in one go, meaning with 'w' instead of 'a'.

Dump dictionary to json file as UTF-8

You need to open the file specifying the file encoding.

with open('Data{0}.json'.format(1), 'w', encoding='utf-8') as file:
json.dump(data, file, ensure_ascii=False)

This way I have dumped your example data sucessfully.

How to write a new dictionary to a json file

There are a few issues here:

file = open('somefile.json', 'a',encoding="utf-8")

You're implicitly assuming that the file will be closed here. That is true on CPython, but not on all Python implementations. A better approach would be:

with open('somefile.json', 'a',encoding="utf-8") as file:
file.write(json_obj)

Because that uses a context manager to explicitly close the file.

Second, you can avoid creating an extra string by writing directly to the file:

with open('somefile.json', 'a',encoding="utf-8") as file:
json.dump(someDict, file)

Third, having multiple JSON objects in a file is not valid JSON. There are a few approaches you could take here. One is to wrap the JSON objects in a list:

[
{
"a": 1,
"b":2,
"c": 3
},
{
"a1": 1,
"b1":2,
"c1": 3
}
]

So, start the file with an open bracket, and write a comma after every JSON object, except the last one, then end the file with a close bracket.

Second approach would be to newline-separate your JSON objects, like this:

{"a": 1,"b":2,"c": 3}
{"a1": 1, "b1":2,"c1": 3}

Each line is a JSON object. You'd read this like so:

with open("filename", "rt") as file:
for line in file:
obj = json.loads(line)
# do something with obj
# ...

The advantage of this approach would be that you can now load each individual JSON object in memory, without having to load the entire file in at once. The disadvantage is that you're no longer writing valid JSON, so you can't use tools like jq on the output. (If you want the best of both worlds, you can use a package like ijson, but that's more complex.)

Correct way to json.dump() nested dictionary AND read back into python w/ json.load()?

Rather than trying to write yourself a valid json just let the json.dump do the heavy-lifting for you. With a main_dict variable to collect the subdicts, you can just dump it to your file:

import json
main_dict = {}

for number in range(1, 6):
letter_dict = {}
letter = input(f'what letter is in position {number}? ')
if letter:
code = input('what code?:')
else:
print('no additional inputs')
break

letter_dict['letter'] = letter
letter_dict['code'] = code
letter_dict['position'] = number

main_dict[f'dict{number}'] = letter_dict

with open('letters.json', 'w') as file:
json.dump(main_dict, file)

Note that I don't open the file letters.txt in append mode because a second run of your program would append another dictionary after the first one, thereby making the json invalid. If you want to append, load the json file in main_dict, add a key-value pair to main_dict and dump again.

How to add a new dictionary into a JSON file?

You need to create a new dictionary containing the information that was entered, and then write the data dictionary back to the file.

data[productname] = {
"id": id,
"price": price,
"quantity": quantity
}
with open("productos.json", "w") as f:
json.dump(data, f)


Related Topics



Leave a reply



Submit