Reputation: 6768
I have a string with a floating point number in it, but I can't get JSON to load it as a decimal.
x = u'{"14": [4.5899999999999999, "susan"]}'
json.loads(x, parse_float = decimal.Decimal)
This returns:
{u'14': [Decimal('4.5899999999999999'), u'susan']}
Any idea how I can make it into the actual "4.59"?
Upvotes: 1
Views: 13627
Reputation: 21
I know this is over a decade later, but just to refine the answer from Alex Martin a bit for anyone coming across this as I did on Google. We can simplify his function to:
json.loads(x, parse_float=lambda x: round(decimal.Decimal(x),2))
The reason is that the value passed into the parse_float
callable by json.loads
is already a str
. Also, this code would not truncate the input value at 64 bits as his would (parsing to a float first will truncate at 64 bit precision).
Obviously, you could use a function rather than a lambda too. I just used the lambda here for brevity.
Upvotes: 2
Reputation: 1186
You can't. That number isn't 4.59, it's 4.589999999999999999, as far as the json parser knows. You'd need to add some more complicated logic that rounds numbers like that, as a wrapper around decimal.Decimal.
Upvotes: 5
Reputation: 881565
You need to define a function that performs whatever rounding you desire, then uses the altered string to build the Decimal
. Your current solution does work perfectly well: it just does exactly what you tell it to, i.e., use the entire string, as opposed to what you desire (and have not told either the code, or us;-).
E.g.:
>>> def doit(s): return decimal.Decimal(str(round(float(s), 2)))
...
>>> json.loads(x, parse_float=doit)
{u'14': [Decimal('4.59'), u'susan']}
>>>
Upvotes: 10