title: Compare Two Different JSON In Python Using Difflib, Showing Only The Differences
body: <p>I am trying to compare 2 different pieces of (Javascript/JSON) code using <code>difflib</code> module in Python 3.8,</p>
  
  <blockquote>
    <p>{"message": "Hello world", "name": "Jack"}</p>
  </blockquote>
  
  <p>and</p>
  
  <blockquote>
    <p>{"message": "Hello world", "name": "Ryan"}</p>
  </blockquote>
  
  <p><strong>Problem:</strong> When these 2 strings are prettified and compared using <code>difflib</code>, we get the inline differences, as well as all the common lines.</p>
  
  <p>Is there a way to only show the lines that differ, in a manner thats clearer to look at? This will help significantly when both files are much larger in size, making it more challenging to identify the changed lines.</p>
  
  <p>Thanks!</p>
  
  <hr>
  
  <p><strong>Actual Output</strong></p>
  
  <pre><code>{
      "message": "Hello world",
      "name": "{J -&gt; Ry}a{ck -&gt; n}"
  }
  </code></pre>
  
  <hr>
  
  <p><strong>Desired Output</strong></p>
  
  <pre><code>    "name": "{J -&gt; Ry}a{ck -&gt; n}"
  </code></pre>
  
  <p>Even better will be something like:</p>
  
  <pre><code>    {"name": "Jack"} -&gt; {"name": "Ryan"}
  </code></pre>
  
  <hr>
  
  <p><strong>Python Code Used</strong></p>
  
  <p><em>We use <code>jsbeautifier</code> here instead of <code>json</code> because the files we are comparing may sometimes be malformed JSON. <code>json</code> will throw an error while <code>jsbeautifier</code> still formats it the way we expect it to.</em></p>
  
  <pre><code>import jsbeautifier
  
  def inline_diff(a, b):
      """
      https://stackoverflow.com/questions/774316/python-difflib-highlighting-differences-inline/47617607#47617607
      """
      import difflib
      matcher = difflib.SequenceMatcher(None, a, b)
      def process_tag(tag, i1, i2, j1, j2):
          if tag == 'replace':
              return '{' + matcher.a[i1:i2] + ' -&gt; ' + matcher.b[j1:j2] + '}'
          if tag == 'delete':
              return '{- ' + matcher.a[i1:i2] + '}'
          if tag == 'equal':
              return matcher.a[i1:i2]
          if tag == 'insert':
              return '{+ ' + matcher.b[j1:j2] + '}'
          assert false, "Unknown tag %r"%tag
      return ''.join(process_tag(*t) for t in matcher.get_opcodes())
  
  
  # File content to compare
  file1 = '{"message": "Hello world", "name": "Jack"}'
  file2 = '{"message": "Hello world", "name": "Ryan"}'
  
  # Prettify JSON
  f1 = jsbeautifier.beautify(file1)
  f2 = jsbeautifier.beautify(file2)
  
  # Print the differences to stdout
  print(inline_diff(f1, f2))
  </code></pre>