How to read a JSON root array into a list? - python

I have a string containing a JSON array:
s = "['GY2_CAMP1', 'GY2_CAMP2', 'GY2_CAMP3', 'GY2_CAMP4', 'GY2_CAMP5']"
I tried to parse it as a JSON:
import json
l = json.loads(s)
I except to get a List, but an Exception has been raised:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/xx/anaconda3/lib/python3.7/json/__init__.py", line 348, in loads
return _default_decoder.decode(s)
File "/home/xx/anaconda3/lib/python3.7/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/home/xx/anaconda3/lib/python3.7/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 2 (char 1)
I am not sure what happens here.

Use ast.literal_eval:
>>> from ast import literal_eval
>>> s = "['GY2_CAMP1', 'GY2_CAMP2', 'GY2_CAMP3', 'GY2_CAMP4', 'GY2_CAMP5']"
>>> literal_eval(s)
['GY2_CAMP1', 'GY2_CAMP2', 'GY2_CAMP3', 'GY2_CAMP4', 'GY2_CAMP5']

Json standard requires double quotes, it does not support single quotes.
That's why you get the error
Thus, the string should be
s = '["GY2_CAMP1", "GY2_CAMP2", "GY2_CAMP3", "GY2_CAMP4", "GY2_CAMP5"]'
Then you get the expected behaviour
import json
l = json.loads(s)
print(l)
>> ['GY2_CAMP1', 'GY2_CAMP2', 'GY2_CAMP3', 'GY2_CAMP4', 'GY2_CAMP5']

First replace the ' with " and then load.
import json
s = "['GY2_CAMP1', 'GY2_CAMP2', 'GY2_CAMP3', 'GY2_CAMP4', 'GY2_CAMP5']"
s.replace("'", "\"")
l = json.loads(s1)
print(l)
will get
['GY2_CAMP1', 'GY2_CAMP2', 'GY2_CAMP3', 'GY2_CAMP4', 'GY2_CAMP5']

Related

Error while converting a list to dict "json.decoder.JSONDecodeError: Expecting value"

import json
string = "'massage':'testing'"
json.loads(string)
But I get this error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/data/data/com.termux/files/usr/lib/python3.10/json/__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "/data/data/com.termux/files/usr/lib/python3.10/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/data/data/com.termux/files/usr/lib/python3.10/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
That is not valid JSON. This works:
import json
string = '{"message": "testing"}'
print(json.loads(string))
Not sure what this has to do with converting lists to dictionaries though.
according to the document
If the data being deserialized is not a valid JSON document, a
JSONDecodeError will be raised.
you have 2 mistake
you miss the brackets in your string
JSON specification - RFC7159 states that a string begins and ends with quotation mark.
That mean single quoute ' has no semantic meaning in JSON and is allowed only inside a string.
result:
import json
string = '{"massage":"testing"}'
json.loads(string)

Python - requests is prefixing extra characters in the output

I am using requests module to run a curl command, not sure why its prefixing ')]}\' in the front of the output, it makes r.json() fail as shown below.
When I paste the URL in a browser and execute, it downloads a .json file, and that file has same characters in the front, Am I missing some option? I need to process the output as json.
>>> r = requests.get('https://gerrit-review-server/a/changes/?q=status:open%20project:myproj/test/a_proj%20change:1510&o=CURRENT_REVISION', verify=False, auth=HTTPBasicAuth('user','pass'),
>>>
>>> r.text
')]}\'\n[{"id":"myproj%2Ftest%2Fa_proj~master~I15790ba05690e0a9984cb05bce06574645274966","project":"myproj/test/a_proj","branch":"master","hashtags":[],"change_id":"I15790ba05690e0a9984cb05bce06574645274966","subject":"Test","status":"NEW","created":"2021-01-27 19:38:57.000000000","updated":"2021-03-21 14:19:42.000000000","submit_type":"MERGE_IF_NECESSARY","mergeable":true,"insertions":1,"deletions":0,"total_comment_count":0,"unresolved_comment_count":0,"has_review_started":true,"_number":1510,"owner":{"_account_id":10008339},"current_revision":"fe3cc60cc66ad6f20c631ee818ccd91955c69d37",<..deleted..>,"description":"Rebase"}},"requirements":[]}]\n'
>>> r.json()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.6/site-packages/requests/models.py", line 900, in json
return complexjson.loads(self.text, **kwargs)
File "/usr/lib64/python3.6/json/__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "/usr/lib64/python3.6/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib64/python3.6/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
>>>
As Carcigenicate says, it seems that the json is wrongly formatted. You can try the loads, and if it fails try to correct it:
r = requests.get(some_url)
try:
data = r.json()
except json.JSONDecodeError:
# cut everything in front of the first "\n"
raw_data = r.text.split("\n", maxsplit=1)[1]
# cut everything behind the last "\n"
raw_data = raw_data.rsplit("\n", maxsplit=1)[0]
# try to load again the json
# If it fails it will raise the exception again
data = json.loads(raw_data)

remove function wrapper with str.replace() in Python

I have some annoying elements in a JSON file that go something like:
"DateTime" : Date(-62135596800000),
"ReceivedDateTime" : Date(-62135596800000)
where serialising this using json.Load() results in an error because Date() is unrecognized.
Traceback (most recent call last):
File "json_parse.py", line 10, in <module>
data = json.load(data_file)
File "C:\Python27\lib\json\__init__.py", line 291, in load
**kw)
File "C:\Python27\lib\json\__init__.py", line 339, in loads
return _default_decoder.decode(s)
File "C:\Python27\lib\json\decoder.py", line 364, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Python27\lib\json\decoder.py", line 382, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
so the easiest thing to do is to remove the Date() wrapper before serialising. I can then convert to proper datetime afterwards.
I can do simple things with str.replace such as:
data.replace("Date(","")
but obviously I am not removing the trailing bracket.
How might I go about doing this?
Cheers.
The more readable way would be to use re library and create regex:
import re
text = '''"DateTime" : Date(-62135596800000),
"ReceivedDateTime" : Date(-62135596800000)'''
pattern = re.compile("Date\((.+)\)")
x = pattern.findall(text)
text2 = text
for i in x:
text2 = text2.replace("Date("+i+")", i)
I wrote this code for you, it should solve the problem.
a = '''"DateTime" : Date(-62135596800000),
"ReceivedDateTime" : Date(-62135596800000)'''
while "Date(" in a: a = (a[:a.index("Date(")+len("Date(")+a[a.index("Date(")+len("Date("):].index(")")] + a[a.index("Date(")+len("Date(")+a[a.index("Date(")+len("Date("):].index(")")+1:]).replace("Date(", "", 1)

Decode JSON with python

I am trying to read data from an arduino via serial which sends a JSON string with the name and values of 6 sensors.
I have checked the string in a JSON validator to be valid. The problem is that I receive an error while attempting to get the dictionary from JSON string.
import json
import serial
import Sensor
s = serial.Serial('COM3',9600)
while True:
m = s.readline()
x = m.decode('UTF-8').rstrip("\n")
b = json.loads(x)
print(b['list'])
{"list":[{"name":"A0","value":"17"},{"name":"A1","value":"39"},
{"name":"A2","value":"13"},{"name":"A3","value":"48"},
{"name":"A4","value":"10"},{"name":"A5","value":"42"}]}
Error
Traceback (most recent call last):
File "C:/Users/andrei_vlad/PycharmProjects/untitled/serial_comm.py", line 9, in <module>
b = json.loads(x)
File "C:\Python34\lib\json\__init__.py", line 318, in loads
return _default_decoder.decode(s)
File "C:\Python34\lib\json\decoder.py", line 343, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "C:\Python34\lib\json\decoder.py", line 361, in raw_decode
raise ValueError(errmsg("Expecting value", s, err.value)) from None
ValueError: Expecting value: line 1 column 1 (char 0)
Update:
I solved the problem. Decode was adding '' before and after the string. I just used x[1:-1] and it works now. Also i had another string which was sent in readline to notify that the connection started.
Decode adds " ' " at the start and the end of the string so I had to remove these two characters using x = x[1:-1]
Solution:
import json
import serial
import Sensor
s = serial.Serial('COM3',9600)
m = s.readline()
print([m])
x =m.decode().strip('\n\r')
x = x[1:-1]
x = json.loads(x)
print(x['list'])

Need a way to load embedded, escaped JSON strings in Python [duplicate]

This question already has answers here:
How can I parse (read) and use JSON?
(5 answers)
Closed last month.
I have to parse the following JSON string:
{"JobDescription":"{\"project\": \"1322\", \"vault\": \"qa-122\"}"}'
If I try to use json.loads, I get the following:
>>> import json
>>> print json.loads('{"JobDescription":"{\"project\": \"1322\", \"vault\": \"qa-122\"}"}')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 338, in loads
return _default_decoder.decode(s)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 365, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/decoder.py", line 381, in raw_decode
obj, end = self.scan_once(s, idx)
ValueError: Expecting , delimiter: line 1 column 22 (char 21)
I don't have any control over the string I receive as its generated by another system.
You are not producing embedded backslashes; Python is interpreting the \" as an escaped quote and the final string just contains the quote:
>>> '{"JobDescription":"{\"project\": \"1322\", \"vault\": \"qa-122\"}"}'
'{"JobDescription":"{"project": "1322", "vault": "qa-122"}"}'
Use a raw string or double the slashes:
>>> r'{"JobDescription":"{\"project\": \"1322\", \"vault\": \"qa-122\"}"}'
'{"JobDescription":"{\\"project\\": \\"1322\\", \\"vault\\": \\"qa-122\\"}"}'
>>> '{"JobDescription":"{\\"project\\": \\"1322\\", \\"vault\\": \\"qa-122\\"}"}'
'{"JobDescription":"{\\"project\\": \\"1322\\", \\"vault\\": \\"qa-122\\"}"}'
This then loads fine:
>>> import json
>>> json.loads('{"JobDescription":"{\\"project\\": \\"1322\\", \\"vault\\": \\"qa-122\\"}"}')
{'JobDescription': '{"project": "1322", "vault": "qa-122"}'}
and you can decode the nested JSON document from there:
>>> decoded = json.loads('{"JobDescription":"{\\"project\\": \\"1322\\", \\"vault\\": \\"qa-122\\"}"}')
>>> json.loads(decoded['JobDescription'])
{'project': '1322', 'vault': 'qa-122'}

Categories