Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

json.load() function decoding integer

Tags:

python

json

I am using json.loads() to identify whether a particular column in data frame is json column. This is how I fdo it inside a function -

df_col.apply( lambda x : json.loads(x) if x is not None else x)

if x is not json, it returns false else true and I use this output to process my data further.

However, I see this failing for integer values casted as char.

For eg,

import json
d1 = 20180304
json.loads(d1) # outputs error, expected string. this is an expected output

d2 = 'abc'
json.loads(d2) #outputs ValueError: No JSON object could be decoded. this is an expected output


d3 = '{"a":"hello"}'
json.loads(d3) #returns true for actual json, expected output

d4 = '123'
json.loads(d4) #outputs true here, casted int(123) as varchar and used function

Due to this behavior with d4, all the int values(that are casted to char) are identified as json elements. Is this the right behavior with josn.loads(). How can I workaround to rightly identify integer columns as non-json elements

like image 614
Abhi Avatar asked Apr 18 '26 13:04

Abhi


2 Answers

If all you are trying to achieve is to modify the behavior of json.loads so that strings representing (non-negative) integers are thrown away, you could make a custom JSONDecoder and roll with that.

class Decoder(json.JSONDecoder):
    def decode(self, s):
        if s.isdigit():
            raise ValueError('all characters in string were digits')
        return super().decode(s)

With this,

In [5]: json.loads('{"a": 123}', cls=Decoder)
Out[5]: {'a': 123}

In [6]: json.loads('123', cls=Decoder)   
ValueError: all characters in string were digits
like image 125
fuglede Avatar answered Apr 21 '26 03:04

fuglede


A number by itself is a perfectly valid JSON text.

If you're trying to apply the obsolete notion of a "JSON document" instead of "JSON text", that was never clearly defined, but the closest thing to a definition goes something like this:

def if_json_doc(s):
    try:
        obj = json.loads(obj)
        return isinstance(obj, (dict, list))
    except JSONDecodeError:
        return False

If you have some other rule, like "JSON object, array, boolean, or undefined, but not null or number", it should be pretty obvious how to modify that to fit your rule. The only hard part is figuring out what rule you actually want.

like image 38
abarnert Avatar answered Apr 21 '26 03:04

abarnert