I wanted to accomplish this same thing, and @Veedrac got pretty close but I did not want quotes around my floats and I also wanted to be able to control the amount of precision. In order to do this I had to use the decimal library as well as the simplejson json dumps implementation (in order to get the use_decimal functionality). Hopefully this will help someone else:
from decimal import Decimal, ROUND_DOWN
import simplejson as sjson
def json_dumps_decimal(data, precision=6):
def recursive_converter(obj):
if isinstance(obj, dict):
return {key: recursive_converter(value) for key, value in obj.items()}
elif isinstance(obj, list):
return [recursive_converter(item) for item in obj]
elif isinstance(obj, float):
decimal_obj = Decimal(obj)
return decimal_obj.quantize(Decimal('1e-{0}'.format(precision)), rounding=ROUND_DOWN)
return obj
return sjson.dumps(recursive_converter(data), use_decimal=True)
Calling this is as follows will yield the following output:
data = {"dictresults": {"val1": 1000, "val2": 1000, "val3": 0.0000012}, "listresults": [0.000034, 0.0, 0.00001], 'flatresult': 0.00000123456}
jsonstr = json_dumps_decimal(data)
print(jsonstr)
{"dictresults": {"val1": 1000, "val2": 1000, "val3": 0.000001}, "listresults": [0.000033, 0.000000, 0.000010], "flatresult": 0.000001}