1

I have a json file in which all integers and floats are represented as strings: [{"x": "123.45", "stuff": "things"}] I've been trying to figure out if there's an easy way to read it in and decode into a dictionary in a such a way that all the number strings get converted back into numbers: {"x": 123.45, "stuff": "things"} I thought JSONDecoder is supposed to have this capability but I can't seem to figure it out. I've tried setting parse_float=Decimal, but that didn't seem to do anything. Does anyone have any ideas without creating a whole new function?

Raksha
  • 1,572
  • 2
  • 28
  • 53
  • 1
    No JSON decoder can know which strings are supposed to be floats and which are supposed to be strings. You’ll have to explicitly cast the specific keys you know should be floats to floats yourself. – deceze Nov 05 '19 at 18:46
  • @deceze, oh, that might be acceptable since the the keys should always be the same. Would you mind posting an answer with how one might do that? Where do I specify a list of keys that will always be floats or integers? Or you mean like make a separate function to do that? – Raksha Nov 05 '19 at 19:06
  • Take a look at this question: https://stackoverflow.com/questions/45068797/how-to-convert-string-int-json-into-real-int-with-json-loads I guess the thing you need is json.loads(c, object_hook=_decode) – Olia Nov 05 '19 at 19:27

2 Answers2

0

Below is an example , you can try

Note : Use isdigit() to check if its integer.

there is no isFloat(), hence created a simple isFloat() function to check for float

def isFloat(string):
    try:
        float(string)
        return True
    except ValueError:
        return False


example = {"x":"123.45",
             "y":"120"}

for key, value in example.items():
    if value.isdigit():
        example[key]=int(value)
    elif isFloat(value):
        example[key]=float(value)


print (example)

output : {'x': 123.45, 'y': 120}

roshan ok
  • 383
  • 1
  • 6
0

Ok, so for the lack of a better option, and because I didn't want a function that throws exceptions, this is what I did:

def change_type(file):
    def to_num(match):
        return ast.literal_eval(match.group())

    data = open(file).read()[1:-1]
    p = re.compile(r'\"([-+]?\d*\.\d+|\d+)\"')
    data_json = loads(p.sub(to_num, data))
    return data_json

this finds all floats and integers among the all possible string values in the json and converts only those strings leaving everything else as is. If anyone has any better suggestions, let me know.

Takes in test.json that is [{"x": "123.45", "stuff": "things"}] and returns {'x': 123.45, 'stuff': 'things'}.

Raksha
  • 1,572
  • 2
  • 28
  • 53