首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >禁用python json.dumps输出中的科学符号

禁用python json.dumps输出中的科学符号
EN

Stack Overflow用户
提问于 2013-09-21 19:12:49
回答 4查看 6.9K关注 0票数 11

json.dumps使用科学表示法输出小浮点数或十进制值,这对于发送输出的json应用程序来说是不可接受的。

代码语言:javascript
复制
>>> import json
>>> json.dumps({"x": 0.0000001})
'{"x": 1e-07}'

我要的是这个输出:

代码语言:javascript
复制
'{"x": 0.0000001}'

最好避免引入额外的依赖项。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-09-21 19:57:00

格式化的一种方法

代码语言:javascript
复制
evil = {"x": 0.00000000001}

是窃取Decimal的"f“格式化程序,这是我发现的避免剪切问题和指数的唯一简单方法,但它不具有空间效率。

代码语言:javascript
复制
class FancyFloat(float):
    def __repr__(self):
        return format(Decimal(self), "f")

要使用它,您可以制作一个“抽取”输入的编码器。

代码语言:javascript
复制
class JsonRpcEncoder(json.JSONEncoder):
    def decimalize(self, val):
        if isinstance(val, dict):
            return {k:self.decimalize(v) for k,v in val.items()}

        if isinstance(val, (list, tuple)):
            return type(val)(self.decimalize(v) for v in val)

        if isinstance(val, float):
            return FancyFloat(val)

        return val

    def encode(self, val):
        return super().encode(self.decimalize(val))

JsonRpcEncoder().encode(evil)
#>>> '{"x": 0.00000000000999999999999999939496969281939810930172340963650867706746794283390045166015625}'

当然,您也可以将十进制移到函数中,并在json.dumps之前调用它。

即使这是一种蹩脚的方法,我也会这么做。

更新

萨姆梅森建议format(Decimal(str(self)), "f"),这仍然应该始终往返,但也产生较短的产出。

票数 7
EN

Stack Overflow用户

发布于 2019-05-09 03:17:58

我无法找到避免将0.00001转换为1e-5的问题的答案,所以我编写了一个pretty_float_json_dumps函数。它在我的项目中很好用!希望能帮上忙!!

代码语言:javascript
复制
def pretty_float_json_dumps(json_obj):
    dumps_str = ""

    if isinstance(json_obj, dict): 
        dumps_str += "{"
        for k,v in json_obj.items():
            dumps_str += json.dumps(k)+":"
            if isinstance(v, float): 
                float_tmp_str = ("%.16f" % v).rstrip("0")
                dumps_str += (float_tmp_str+'0' if float_tmp_str.endswith('.') else float_tmp_str) + ','
            elif isinstance(v, list) or isinstance(v, dict): 
                dumps_str += pretty_float_json_dumps(v)+','
            else:
                dumps_str += pretty_float_json_dumps(v)+','
        if dumps_str.endswith(','):
            dumps_str = dumps_str[:-1]
        dumps_str += "}"
    elif isinstance(json_obj, list): 
        dumps_str += "["
        for v in json_obj:
            if isinstance(v, float): 
                float_tmp_str = ("%.16f" % v).rstrip("0")
                dumps_str += (float_tmp_str+'0' if float_tmp_str.endswith('.') else float_tmp_str) + ','
            elif isinstance(v, list) or isinstance(v, dict): 
                dumps_str += pretty_float_json_dumps(v)+','
            else:
                dumps_str += pretty_float_json_dumps(v)+','
        if dumps_str.endswith(','):
            dumps_str = dumps_str[:-1]
        dumps_str += "]"
    else:
        dumps_str += json.dumps(json_obj)
    return dumps_str
票数 1
EN

Stack Overflow用户

发布于 2021-03-23 16:59:10

这是补充评论,不是避免json.dumps中的科学符号的完整答案。通过额外的一轮解析,parse_float选项在json.loads上可以帮助做一些事情。

代码语言:javascript
复制
$ python
Python 3.7.10 | packaged by conda-forge | (default, Feb 19 2021, 16:07:37) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import json
>>> data = {"x": 0.0000001}
>>> json.dumps(data)
'{"x": 1e-07}'
>>> data = json.loads(json.dumps(data), parse_float=lambda x: round(float(x), 6))
>>> json.dumps(data)
'{"x": 0.0}'

这只会避免对舍入为零的小值进行科学表示法。虽然这对于大型数据集并不有效,但它可以在某些用例中有所帮助。这并不能完全避免科学表示法。

代码语言:javascript
复制
>>> data = {"x": 0.00001}
>>> data = json.loads(json.dumps(data), parse_float=lambda x: round(float(x), 6))
>>> json.dumps(data)
'{"x": 1e-05}'
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18936554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档