victor
victor

Reputation: 6768

How do I make Json's parse_float=decimal.Decimal round the number to two decimal points?

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

Answers (3)

UglyBug
UglyBug

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

inklesspen
inklesspen

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

Alex Martelli
Alex Martelli

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

Related Questions