As of Python 3.5, you can merge two dicts with:
merged = {**dictA, **dictB}
(https://www.python.org/dev/peps/pep-0448/)
So:
jsonMerged = {**json.loads(jsonStringA), **json.loads(jsonStringB)}
asString = json.dumps(jsonMerged)
etc.
EDIT 2 Nov 2024: Pretty sure we can now do merged = dictA | dictB
» pip install jsonmerge
As of Python 3.5, you can merge two dicts with:
merged = {**dictA, **dictB}
(https://www.python.org/dev/peps/pep-0448/)
So:
jsonMerged = {**json.loads(jsonStringA), **json.loads(jsonStringB)}
asString = json.dumps(jsonMerged)
etc.
EDIT 2 Nov 2024: Pretty sure we can now do merged = dictA | dictB
Assuming a and b are the dictionaries you want to merge:
c = {key: value for (key, value) in (a.items() + b.items())}
To convert your string to python dictionary you use the following:
import json
my_dict = json.loads(json_str)
Update: full code using strings:
# test cases for jsonStringA and jsonStringB according to your data input
jsonStringA = '{"error_1395946244342":"valueA","error_1395952003":"valueB"}'
jsonStringB = '{"error_%d":"Error Occured on machine %s in datacenter %s on the %s of process %s"}' % (timestamp_number, host_info, local_dc, step, c)
# now we have two json STRINGS
import json
dictA = json.loads(jsonStringA)
dictB = json.loads(jsonStringB)
merged_dict = {key: value for (key, value) in (dictA.items() + dictB.items())}
# string dump of the merged dict
jsonString_merged = json.dumps(merged_dict)
But I have to say that in general what you are trying to do is not the best practice. Please read a bit on python dictionaries.
Alternative solution:
jsonStringA = get_my_value_as_string_from_somewhere()
errors_dict = json.loads(jsonStringA)
new_error_str = "Error Ocurred in datacenter %s blah for step %s blah" % (datacenter, step)
new_error_key = "error_%d" % (timestamp_number)
errors_dict[new_error_key] = new_error_str
# and if I want to export it somewhere I use the following
write_my_dict_to_a_file_as_string(json.dumps(errors_dict))
And actually you can avoid all these if you just use an array to hold all your errors.
python - Combining two JSON objects in to one - Stack Overflow
is it possible merge two json object
Merge two json object in python - Stack Overflow
Python - Combining two json objects - Stack Overflow
Hello everyone,
I am trying to merge two JSON files, but I couldn't find any quick package that can do this. One file contains the base policy, while the other includes additional files for excluding special configurations.
My goal is to merge these two JSON files of AntiVirus policy, which contain arrays and numerous elements, without overwriting any data. I was wondering what the best approach would be to accomplish this.
If its element just uses the value of the other files.
If its array just append new elements.
What is best way to achieve this goal?
Thanks all
You can't do it once they're in JSON format - JSON is just text. You need to combine them in Python first:
data = { 'obj1' : obj1, 'obj2' : obj2 }
json.dumps(data)
Not sure if I'm missing something, but I think this works (tested in python 2.5) with the output you specify:
import simplejson
finalObj = { 'obj1': obj1, 'obj2': obj2 }
simplejson.dumps(finalObj)
In json module, dumps convert python object to a string, and loads convert a string into python object. So in your original codes, you just try to concat two json-string. Try to code like this:
import json
from collections import defaultdict
def merge_dict(d1, d2):
dd = defaultdict(list)
for d in (d1, d2):
for key, value in d.items():
if isinstance(value, list):
dd[key].extend(value)
else:
dd[key].append(value)
return dict(dd)
if __name__ == '__main__':
json_str1 = json.dumps({"a": [1, 2]})
json_str2 = json.dumps({"a": [3, 4]})
dct1 = json.loads(json_str1)
dct2 = json.loads(json_str2)
combined_dct = merge_dict(dct1, dct2)
json_str3 = json.dumps(combined_dct)
# {"a": [1, 2, 3, 4]}
print(json_str3)
json.dumps() converts a dictionary to str object, not a json(dict) object.
So, adding some dumps statement in your code shows that the type is changed to str after using json.dumps() and with + you are effectively concatenating the two string and hence you get the concatenated output.
Further, to merge the two dictionaries for your simple case, you can just use the append:
import json
json_obj = json.dumps({"a": [1,2]})
json_obj1 = json.dumps({"a": [3,4]})
print(type(json_obj1)) # the type is `str`
json_obj += json_obj1 # this concatenates the two str objects
json_obj = {"a": [1,2]}
json_obj1 = {"a": [3,4]}
json_obj["a"].extend(json_obj1["a"])
print(json_obj)
- First off, if you want reusability, turn this into a function. The function should have it's respective arguments.
- Secondly, instead of allocating a variable to store all of the JSON data to write, I'd recommend directly writing the contents of each of the files directly to the merged file. This will help prevent issues with memory.
- Finally, I just have a few nitpicky tips on your variable naming. Preferably,
headshould have a name more along the lines ofmerged_files, and you shouldn't be usingfas an iterator variable. Something likejson_filewould be better.
This is essentially alexwlchan's comment spelled out:
Parsing and serializing JSON doesn't come for free, so you may want to avoid it. I think you can just output "[", the first file, ",", the second file etc., "]" and call it a day. If all inputs are valid JSON, unless I'm terribly mistaken, this should also be valid JSON.
In code, version 1:
def cat_json(outfile, infiles):
file(outfile, "w")\
.write("[%s]" % (",".join([mangle(file(f).read()) for f in infiles])))
def mangle(s):
return s.strip()[1:-1]
Version 2:
def cat_json(output_filename, input_filenames):
with file(output_filename, "w") as outfile:
first = True
for infile_name in input_filenames:
with file(infile_name) as infile:
if first:
outfile.write('[')
first = False
else:
outfile.write(',')
outfile.write(mangle(infile.read()))
outfile.write(']')
The second version has a few advantages: its memory requirements should be something like the size of the longest input file, whereas the first requires twice the sum of all file sizes. The number of simultaneously open file handles is also smaller, so it should work for any number of files.
By using with, it also does deterministic (and immediate!) deallocation of file handles upon leaving each with block, even in python implementations with non-immediate garbage collection (such as pypy and jython etc.).