Simplejson strange behavior - python

So In python I make a dictionary in JSON structure
>>> a = {"name":'nikhil',"age":25}
Now I check if a is a Valid JSON using http://jsonlint.com/
. I get it's valid.
Now I do :
>>> b = simplejson.dumps(a)
>>> b= '{"age": 25, "name": "nikhil"}'
Now I do:
>>> c = simplejson.loads(b)
>>> c = {'age': 25, 'name': 'nikhil'}
Now I check if c is a Valid JSON I get error.
Why is Simplejson is not able to convert JSON string back to valid JSON? when I started with a valid JSON only?

You are confusing JSON with Python here. b is a JSON-formatted string, c is a Python object.
Python syntax just happens to look a lot like JSON (JavaScript) in that respect.
Python strings can use either ' or ", depending on the contents; JSON always uses ". You entered a using double quotes for the keys, single quotes for the one string value; if you asked Python to echo it back for you you'll find it'll be shown with only single quotes.
Python booleans are True or False, JSON uses true and false.
The JSON 'empty' value is null, Python uses None instead.
See the Encoders and Decoders section of the json module for an overview how JSON and Python objects are mapped.

Related

json.loads change " " to single quote

I am writing a program to call an API. I am trying to convert my data payload into json. Thus, I am using json.loads() to achieve this.
However, I have encountered the following problem.
I set my variable as following:
apiVar = [
"https://some.url.net/api/call", #url
'{"payload1":"email#user.net", "payload2":"stringPayload"}',#payload
{"Content-type": "application/json", "Accept": "text/plain"}#headers
]
Then I tried to convert apiVar[1] value into json object.
jsonObj = json.loads(apiVar[1])
However, instead of giving me output like the following:
{"payload1":"email#user.net", "payload2":"stringPayload"}
It gives me this instead:
{'payload1':'email#user.net', 'payload2':'stringPayload'}
I know for sure that this is not a valid json format. What I would like to know is, why does this happen? I try searching a solution for it but am not able to find anything on it. All code examples suggest it should have given me the double quote instead.
How should I fix it so that it will give the double quote output?
json.loads() takes a JSON string and converts it into the equivalent Python datastructure, which in this case is a dict containing strings. And Python strings display in single quotes by default.
If you want to convert a Python datastructure to JSON, use json.dumps(), which will return a string. Or if you're outputting straight to a file, use json.dump().
In any case, your payload is already valid JSON, so the only reason to load it is if you want to make changes to it before calling the API.
You need to use the json.dumps to convert the object back into json format.
The string with single quotes that you are reverencing is probably a str() or repr() method that is simply used to visualize the data as a python object (dictionary) not a json object. try taking a look at this:
print(type(jsonObj))
print(str(jsonObj))
print(json.dumps(jsonObj))

Python output a json style string

here defining a variable:
sms_param = '{\"website\":\"hello\"}'
and it print out ok like this : {"website":"hello"}, but i want to pass a dynamic value to its value, so its format should like this: {\"website\":\"{0}\"}.format(msg), but it output a KeyError, I have no idea of this Error, and change all kinds of string format such as triple quotation and change {0} with %s, but all seems useless. how can i solve it.
My suggestion is using json.loads()
>>> sms_param = '{\"website\":\"hello\"}'
>>> import json
>>> json.loads(sms_param)
{'website': 'hello'}
What you can do is using json.loads() convert the json string to dictionary and then change the value, finally convert it back to string

Json object is printed in strange format in Python

so i do this get request to a Steam page where it responds this JSON:
{"success":true,"lowest_price":"$2.23","volume":"2,842","median_price":"$2.24"}
My objective is to transform it into a dictionary in Python, but what i get when i return the JSON object in my function is this:
{u'volume': u'2,842', u'median_price': u'2,02€ ',
u'lowest_price': u'1,99€ ', u'success': True} (notice the u').
What can i do to eliminate the u's?
You're seeing Python letting you know that the strings you're printing are unicode strings. Unless the output you're seeing really matters (e.g., it's input for something else), you can generally disregard the leading 'u' character until you run into issues with unicode output.
There are a litany of stack overflow questions which address this.
Python string prints as [u'String']
What's the u prefix in a python string
Printing a string prints 'u' before the string in Python?
And a lot more....
You could import json module and use json.dumps to prettify your output.
import json
response = {"success":True,"lowest_price":"$2.23","volume":"2,842","median_price":"$2.24"}
print json.dumps(response, indent=2)

JSON like string with unicode to valid JSON

I get a string which resembles JSON and I'm trying to convert it to valid JSON using python.
It looks like this example, but the real data gets very long:
{u'key':[{
u'key':u'object',
u'something':u'd\xfcabc',
u'more':u'\u2023more',
u'boolean':True
}]
}
So there are also a lot of special characters, as well as the "wrong" boolean which should be just lowercase letters.
I don't have any influence over the data I get, I just have to parse it somehow and extract some stuff from it.
I tried to replace the special characters and everything and force it to be a valid JSON, but it is not at all elegant and I could easily forget to replace one type of special character.
You can use literal_eval from the ast module for this.
ast.literal_eval(yourString)
You can then convert this Object back to JSON.
JSON spec only allows javascript data (true, false for booleans, null, undefined for None properties, etc)
The string of this question, it's an python object, so as #florian-dreschsler says, you must use literal_eval from the ast module
>>> import ast
>>> json_string = """
... {u'key':[{
... u'key':u'object',
... u'something':u'd\xfcabc',
... u'more':u'\u2023more',
... u'boolean':True, #this property fails with json module
... u'null':None, #this property too
... }]
... }
... """
>>> ast.literal_eval(json_string)
{u'key': [{u'boolean': True, u'null': None, u'something': u'd\xfcabc', u'key': u'object', u'more': u'\u2023more'}]}

Convert unicode string dictionary into dictionary in python

I have unicode u"{'code1':1,'code2':1}" and I want it in dictionary format.
I want it in {'code1':1,'code2':1} format.
I tried unicodedata.normalize('NFKD', my_data).encode('ascii','ignore') but it returns string not dictionary.
Can anyone help me?
You can use built-in ast package:
import ast
d = ast.literal_eval("{'code1':1,'code2':1}")
Help on function literal_eval in module ast:
literal_eval(node_or_string)
Safely evaluate an expression node or a string containing a Python expression. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.
You can use literal_eval. You may also want to be sure you are creating a dict and not something else. Instead of assert, use your own error handling.
from ast import literal_eval
from collections import MutableMapping
my_dict = literal_eval(my_str_dict)
assert isinstance(my_dict, MutableMapping)
EDIT: Turns out my assumption was incorrect; because the keys are not wrapped in double-quote marks ("), the string isn't JSON. See here for some ways around this.
I'm guessing that what you have might be JSON, a.k.a. JavaScript Object Notation.
You can use Python's built-in json module to do this:
import json
result = json.loads(u"{'code1':1,'code2':1}") # will NOT work; see above
I was getting unicode error when I was reading a json from a file. So this one worked for me.
import ast
job1 = {}
with open('hostdata2.json') as f:
job1= json.loads(f.read())
f.close()
#print type before converting this from unicode to dic would be <type 'unicode'>
print type(job1)
job1 = ast.literal_eval(job1)
print "printing type after ast"
print type(job1)
# this should result <type 'dict'>
for each in job1:
print each
print "printing keys"
print job1.keys()
print "printing values"
print job1.values()
You can use the builtin eval function to convert the string to a python object
>>> string_dict = u"{'code1':1, 'code2':1}"
>>> eval(string_dict)
{'code1': 1, 'code2': 1}

Categories

Resources