简体   繁体   中英

How to get rid of quotes in a json string resulting from converting scientific notation to exact value

I have a list of dictionary items that I will iterate through to update into a dictionary. That dictionary will be converted to a json string which will get inserted into an SQL database. My problem is that some of those values in the dictionary items can be very small (or large), and thus Python automatically puts it in scientific notation.

For example, I have this dictionary: {"Name": {"Key1": "0.000006", "Key2": "0.0000000001"}} . I've been able to convert scientific notation to an exact value string using the function that I created below. But now I have to keep it as a string because as soon as I cast float() on that string, it goes back to scientific notation. So then when I use json.dumps() to put the dictionary into a json string, it creates unnecessary quotes around those string-casted float values: "{"Name": {"Key1": "0.000006", "Key2": "0.0000000001"}}" . How do I get rid of those quotes?

def format_float(self, value):
    value_string = str(value)
    # Anything smaller than or equal to 1e-5 will get converted to scientific notation
    # If the value is in scientific notation
    if 1e-323 <= abs(value) <= 1e-5:
        # Split the string by the exponent sign
        split_value_string = value_string.split("e-")
        # Get the exponential
        exponential = int(split_value_string[1])
        # If there is a decimal, there could be digits after the decimal
        if "." in split_value_string[0]:
            precision = len(split_value_string[0].split(".")[1])
        else:
            precision = 0
        f = "%.*f" % (exponential + precision, value)
    elif value == float("inf") or value == float("-inf"):
        return value
    # Not in scientific notation
    else:
        if "." in value_string:
            precision = len(value_string.split(".")[1])
        else:
            precision = 0
        f = "%.*f" % (precision, value)
    # No decimal
    if "." not in f:
        f += ".0"

    p = f.partition(".")

    s = "".join((p[0], p[1], p[2][0], p[2][1:].rstrip("0")))  # Get rid of the excess 0s

    return s

float() shouldn't be putting anything in scientific notation. It's just that when python prints a float that's really long, it prints it in scientific notation. try using json.dumps() while keeping the values as float , it should give you what you want.

edit : let me rephrase. json.dumps() will give you valid json. the json specification allows for floats to be given as scientific notation, so the fact that it's in scientific notation shouldn't be a problem. That is, if you load what has been dumped, it will give you a float , which you can do math on as you would expect. eg: type(json.loads(json.dumps({'lol':1e-8}))['lol']) gives me float

If you REALLY need to have the json not have scientific notation in it, for example if the thing that will read the json is not standards-compliant, then you can use json.dumps() to dump it as a string, then use re.sub() to replace the numbers.

precision = 10
re.sub('\d+e-?\d+',lambda x: '%.*f'%(precision,float(x.group())),json.dumps({'lol':1e-8}))

gives me

'{"lol": 0.0000000100}'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM