JSON diff in Python vs online
You can do a JSON diff in Python with a few lines and no packages. You can also paste both files into an online JSON diff checker. This page shows both ways, so you can pick the one that fits the job.
The short version
Use Python when the check is part of a script or a test. Use an online JSON diff tool when you want to look at the changes once, or when you want to send the result to someone.
Step 1: check if two JSON files are equal
Load both files with json.load. Python then compares the parsed values. Key order and spacing do not matter.
import json, sys
with open(sys.argv[1]) as f1, open(sys.argv[2]) as f2:
a, b = json.load(f1), json.load(f2)
print("equal" if a == b else "different") This tells you if the files differ. It does not tell you where.
Step 2: list every change by path
This function walks both values at the same time. It yields the kind of change, the path, the old value and the new value.
import json
def diff(a, b, path="$"):
"""Yield (kind, path, old, new) for every difference between two parsed JSON values."""
if isinstance(a, dict) and isinstance(b, dict):
for key in sorted(a.keys() | b.keys()):
child = f"{path}.{key}"
if key not in b:
yield ("removed", child, a[key], None)
elif key not in a:
yield ("added", child, None, b[key])
else:
yield from diff(a[key], b[key], child)
elif isinstance(a, list) and isinstance(b, list):
for i in range(max(len(a), len(b))):
child = f"{path}[{i}]"
if i >= len(b):
yield ("removed", child, a[i], None)
elif i >= len(a):
yield ("added", child, None, b[i])
else:
yield from diff(a[i], b[i], child)
elif a != b or type(a) is not type(b):
yield ("changed", path, a, b)
old = json.loads('{"name": "Ada", "age": 36, "tags": ["a", "b"], "city": "London"}')
new = json.loads('{"age": 37, "name": "Ada", "tags": ["a", "c", "d"], "email": "ada@example.com"}')
for kind, path, before, after in diff(old, new):
print(kind, path, json.dumps(before), json.dumps(after)) The output for the example:
changed $.age 36 37
removed $.city "London" null
added $.email null "ada@example.com"
changed $.tags[1] "b" "c"
added $.tags[2] null "d" The type(a) is not type(b) check matters. In Python, 1 == True is True, so without it a number that became a boolean would be reported as equal.
Step 3: get a line diff with difflib
If you only want a text view, format both documents the same way and compare the lines. Sorting the keys removes false changes from key order.
import difflib, json
a = json.dumps({"a": 1, "b": [1, 2]}, indent=2, sort_keys=True).splitlines()
b = json.dumps({"a": 2, "b": [1, 2, 3]}, indent=2, sort_keys=True).splitlines()
print("\n".join(difflib.unified_diff(a, b, "old.json", "new.json", lineterm=""))) The result is a unified diff, the same format Git uses:
--- old.json
+++ new.json
@@ -1,7 +1,8 @@
{
- "a": 1,
+ "a": 2,
"b": [
1,
- 2
+ 2,
+ 3
]
} Where the Python code falls short
- Array order. The function above compares items by position. If the same items come in another order, it reports many changes.
- Matching by id. To pair array items by a key such as
id, you must write that code yourself. - Ignored fields. Fields such as
updatedAtneed an extra filter step. - Big numbers. Python keeps big integers exact. A float such as
1.0equals1, which may or may not be what you want. - Reading the result. Printed lines are fine for ten changes. They are hard to read for hundreds.
JSON diff online: when it is faster
For a one-off check, an online JSON diff viewer saves the code. On the JSON diff checker you paste the two documents and read a list of changes with the path, the old value and the new value. It can ignore array order, match array items by id and ignore fields. Everything runs in your browser, and your JSON is not sent to a server.
Python or online?
| Situation | Better fit |
|---|---|
| A check in a test or a build script | Python |
| A one-time look at two API responses | Online |
| Arrays in a different order, or matched by id | Online, or extra Python code |
| Sharing the result with a colleague | Online, with a share link |
| Files you must not paste into a web page | Python |
Ready to try it? Open the online JSON compare tool and press Sample to see every kind of change.