9

Why is json.loads() returning a string? Here's is my code:

import json

d = """{
    "reference": "123432",
    "business_date": "2019-06-18",
    "final_price": 40,
    "products": [
        {
            "quantity": 4,
            "original_price": 10,
            "final_price": 40,
        }
    ]
}"""

j = json.loads(json.dumps(d))
print(type(j))

Output:

<class 'str'>

Shouldn't it returning a json object? What change is required here?

Zid
  • 439
  • 1
  • 4
  • 18
  • remove the quotes in d before and after, `{` and `}` resp. – Siddharth Das Jun 24 '19 at 11:26
  • ```{ "reference": "123432", "business_date": "2019-06-18", "final_price": 40, "products": [ { "quantity": 4, "original_price": 10, "final_price": 40, } ] } ```JSON Data ```Invalid JSON: Expecting property name enclosed in double quotes: line 10 column 9 (char 215) None [Program finished]```Commenting for future readers – Subham Mar 17 '21 at 10:23

4 Answers4

6

Two points:

  1. You have a typo in your products key : "final_price": 40, should be "final_price": 40 (without comma)
  2. j should be json.loads(d)

Output

dict

EDIT

Reasons why you can not have a trailing comma in a json objects are explained in this post Can you use a trailing comma in a JSON object?

Unfortunately the JSON specification does not allow a trailing comma. There are a few browsers that will allow it, but generally you need to worry about all browsers.

Sebastien D
  • 4,369
  • 4
  • 18
  • 46
3

ast.literal_eval: Safely evaluate an expression node or a string containing a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, None, bytes and sets. more details

import ast

d = """{
    "reference": "123432",
    "business_date": "2019-06-18",
    "final_price": 40,
    "products": [
        {
            "quantity": 4,
            "original_price": 10,
            "final_price": 40,
        }
    ]
}"""

data = ast.literal_eval(d)

print(data)
print(type(data))

O/P:

{'reference': '123432', 'business_date': '2019-06-18', 'final_price': 40, 'products': [{'quantity': 4, 'original_price': 10, 'final_price': 40}]}
<class 'dict'>
bharatk
  • 4,202
  • 5
  • 16
  • 30
2

1). The type of d AND j will remain same.

import json

d = """{
 "reference": "123432",
 "business_date": "2019-06-18",
 "final_price": 40,
 "products": [
    {
        "quantity": 4,
        "original_price": 10,
        "final_price": 40,
    }
    ]
}"""
print(type(d))

j = json.loads(json.dumps(d))
print(type(j))

2). Now Both have Dictionary type:-

import json

d = {
 "reference": "123432",
 "business_date": "2019-06-18",
 "final_price": 40,
 "products": [
    {
        "quantity": 4,
        "original_price": 10,
        "final_price": 40,
    }
    ]
}
print(type(d))

j = json.loads(json.dumps(d))
print(type(j))

This is the reason we use json format. I hope this may help you.

Rahul charan
  • 765
  • 7
  • 15
1

In your code, d is supposed to be a JSON string. If it were, you wouldn't therefore need to dump it before loading it.

When I remove the string quotes, meaning that the json.dumps call is working on a dict not a string everything seems to come out fine:

import json

d = {
    "reference": "123432",
    "business_date": "2019-06-18",
    "final_price": 40,
    "products": [
        {
            "quantity": 4,
            "original_price": 10,
            "final_price": 40,
        }
    ]
}

j = json.loads(json.dumps(d))
print(type(j))

prints out

<class 'dict'>

Note, however, that trying to apply json.loads to the existing string will produce an error because JSON is less forgiving than Python, and doesn't allow dangling commas at the end of lists and dicts (see the "final_price" element definition).

holdenweb
  • 33,305
  • 7
  • 57
  • 77
  • It is a json string. But since it was not working simply with json.loads(s), I tried to dump it before loading it and it worked. But the issue was the trailing comma after 40 in 'final_price'. Removing it fixed the issue. Thanks for input. – Zid Jun 24 '19 at 12:25
  • 1
    That was my point - with the additional comma, it was no longer valid JSON, so passing it to `json.loads` errored with `json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 10 column 9 (char 215)`. Anyway, glad it's resolved. – holdenweb Jun 24 '19 at 12:33
  • 1
    You are right. It's not json string anymore although earlier it was. Actually its a subset of a big json string I got from json.dumps(json_obj). Editing it in notepad++ left that trailing comma. – Zid Jun 24 '19 at 13:00