0

I have 2 files like these:

file1.json

[
  {
    "name": "john",
    "version": "0.0"
  },
  {
    "name": "peter",
    "version": "1.0"
  },
  {
    "name": "bob",
    "version": "2.0",
    "single": "true"
  }
]

file2.json

[
  {
    "name": "jane",
    "version": "0.0"
  },
  {
    "name": "peter",
    "version": "1.0"
  },
  {
    "name": "bob",
    "version": "2.0",
    "single": "true"
  }
]

I want to compare the "name" values in file1.json with the "name" values in file2.json. If file2.json has some "name" values not in file1.json, I want to append that json object to file1.json.

For the above 2 files, I want file1 to be appended with the "name": "jane" object since that is not present in file1. So file1 should be updated to:

[
  {
    "name": "john",
    "version": "0.0"
  },
  {
    "name": "peter",
    "version": "1.0"
  },
  {
    "name": "bob",
    "version": "2.0",
    "single": "true"
  },
  {
    "name": "jane",
    "version": "0.0"
  }
]

What I have tried:

with open('file1.json', 'r') as file1, open('file2.json', 'r') as file2:
    file1_json = json.load(file1)
    file2_json = json.load(file2)

for object in file2_json:
    if object['name'] not in file1_json.values():
        file1_json.update(object)

with open('file1.json', 'w') as file1:
    json.dump(file1_json, file1, indent=4)
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
cttrader
  • 25
  • 3
  • 1
    What error are you getting? Or what output? And what did you expect? – cafce25 Dec 05 '22 at 23:14
  • What the result that you're getting? `file1_json` is a `list of dicts`, not a `dict`, thus calling `file1_json.values()` will result in `AttributeError`. You will need a second inner `for` loop to iterate over `file1_json` just like you did with `file2_json`. – Vasilis G. Dec 05 '22 at 23:15
  • 1
    Your JSON files each contain a `list`. So `file1_json.values()` doesn't make sense. – Woodford Dec 05 '22 at 23:20

4 Answers4

0

Collect the names in file1_json, find the missing names in file2_json, then add them to file1_json:

import json

with open('file1.json', 'r') as file1, open('file2.json', 'r') as file2:
    file1_json = json.load(file1)
    file2_json = json.load(file2)

names = [o['name'] for o in file1_json]
missing = [o for o in file2_json if o['name'] not in names]
file1_json.extend(missing)

with open('file1.json', 'w') as file1:
    json.dump(file1_json, file1, indent=2)

Output:

[
  {
    "name": "john",
    "version": "0.0"
  },
  {
    "name": "peter",
    "version": "1.0"
  },
  {
    "name": "bob",
    "version": "2.0",
    "single": "true"
  },
  {
    "name": "jane",
    "version": "0.0"
  }
]
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
0

This should work if all dictionary values are immutable (which they are):

with open('file1.json', 'r') as file1, open('file2.json', 'r') as file2:
    file1_json = json.load(file1)
    file2_json = json.load(file2)
print([dict(s) for s in set(frozenset(d.items()) for d in file1_json+file2_json)])
Lexpj
  • 921
  • 2
  • 6
  • 15
0

You could create an index into json2 to speed lookups. Then take the set of names from each and subtract. The result is the missing names. Use the index to add the missing values.

with open('file1.json', 'r') as file1, open('file2.json', 'r') as file2:
    file1_json = json.load(file1)
    file2_json = json.load(file2)

idx2 = {d["name"]:d for d in file2_json}
missing = set(idx2) - set(d["name"] for d in file1_json)
file1_json.extend(idx2[name] for name in missing)
tdelaney
  • 73,364
  • 6
  • 83
  • 116
-1

I believe what you want is to merge dictionaries essentially. The fact it comes from a json does not really matter here. Take a look at this. https://stackoverflow.com/a/62820532/4944708

Here's the full solution, assuming you have read the jsons in:

def to_dict(json_):
     return {item['name']: item for item in json_}

list({**to_dict(json1), **to_dict(json2)}.values())
Szilard
  • 79
  • 4