0

I'm trying to convert a python dictionary to the target JSON object below. I figured I'd use json.dumps() (as per this thread) but the result is not the same nevertheless. The target has some unconvential spacing in it, but I'm not allowed to change it or edit them out.

Any idea how to approach this?

import json

dict= {"token":{"name":"John Doe","code":"123456789"}}
target = '{ "token":{ "name":"John Doe", "code":"123456789" } }'

print(json.dumps(dict))
print(json.loads(json.dumps(dict)))
print(target)

>>>{"token": {"name": "John Doe", "code": "123456789"}}
>>>{'token': {'name': 'John Doe', 'code': '123456789'}}
>>>{ "token":{ "name":"John Doe", "code":"123456789" } }

For additional context, I'm trying to prepare the argument passed through Bambora's payment API. See the cURL example associated to this here.

Max Vallee
  • 406
  • 5
  • 15
  • It's almost certainly just a spacing issue. The more interesting question would be if `json.loads(json.dumps(dict)) == json.loads(target)` – Adam Smith Oct 06 '20 at 04:20
  • String comparison checks for an exact match, including whitespace. `dumps` with default settings makes some particular assumptions about where whitespace does and does not go that are not matched by the string you have in `target`. You can print `json.dumps(dict)` to see what it's actually producing. Separately, I would recommend against using Python keywords like `dict` as variable names. – Nathan Pierson Oct 06 '20 at 04:20
  • Since you're comparing string values, the two strings have to be exactly the same for you to get a True result. Even having a single space in one result but not in the other will lead to a False result, even though the two strings may functionally be identical. Looking at your target string, the spacing seems non-standard to me, so I would guess that it would not match the output of `json.dumps()`. You could read the target string with `json.loads` and then dump it back with `json.dumps()`. Then you should be able to do the comparison of the two strings and get a useful result. – CryptoFool Oct 06 '20 at 04:21

3 Answers3

1

Since you're comparing strings, you'll get a False result if even one space is different between the two strings. This can happen even if the two structures are actually the same in terms of their structure and data. What you really want to do is find a way to remove non-substantive formatting issues from the equation.

Here's how to fix your code to take away the problem of differences in spacing and other non-substantive differences:

import json

dict= {"token":{"name":"John Doe","code":"123456789"}}
target = json.dumps(json.loads('{ "token":{ "name":"John Doe", "code":"123456789" } }'))

print(target == json.dumps(dict))

Result:

True
CryptoFool
  • 21,719
  • 5
  • 26
  • 44
  • See above my modified question. I've tried this but the string returned (with .dumps() and .loads() combined) has single quotations ', whereas the target comes out with double quotations ''. – Max Vallee Oct 06 '20 at 04:47
  • 1
    The first and third output lines are strings containing JSON encoded data. JSON always uses double quotes. The second output line is not JSON. It is how Python is choosing to show you the value of your in-memory data structure. It just so happens that the two formats are the same in this case except that Python chooses to use single quotes when it prints the data structure. All three lines are in fact valid Python syntax. You could use any of them in Python code to reconstruct the data structure without using a JSON decoder. The second line will fail if you try to read it as JSON. – CryptoFool Oct 06 '20 at 05:17
1

There are some unnecessary whitespaces in your target JSON.

target = '{ "token":{ "name":"John Doe", "code":"123456789" } }'

You can use the separators argument to get a space after the comma separators.

json.dumps(dict, separators=(', ', ':'))

In order to get the spaces around the curly braces, I am afraid, you will need to use a regular expression based substitution.

Muntasir Wahed
  • 297
  • 2
  • 11
0

json.dumps() returns {"token": {"name": "John Doe", "code": "123456789"}}'

It has no spaces at end of each brackets { and }, but your one string has.

This code returns True:

json.dumps(dict) == '{"token": {"name": "John Doe", "code": "123456789"}}'

Let's take a closer look "white spaces".

The differences are: (your vs. json.dumps)

  • "code:"123" vs. "code": "123"
  • { "token"... vs. {"token"...
  • "token":{ "name"... vs. "token": {"name":..

OR, you could compare two value with no spaces as like:

json.dumps(dict).replace(' ', '') == target.replace(' ', '')

It returns True as well.

Joona Yoon
  • 314
  • 3
  • 16