当值在键内时添加很多小数:(数组)对象

Adding lots of decimals when value is inside a key: (array) object

编辑:这是在 python 2.7.7

有人遇到过这个吗?我需要将一个键值对对象序列化为一个字符串,其中每个键包含一个浮点数。

可以有任意数量的条目(在这个例子中我只演示了一个,“测试”)。

似乎在评估 整个对象时 ,Python 可以在值上加上小数,而当我们独立地查看那些完全相同的值时(在对象),它们看起来“正常”。

我需要一种方法使最终的序列化对象包含原始值(在本例中为 0.08);或强迫他们使用 2DP 的方法。

userConstraints = {
        "test": 0.08
    }

print userConstraints["test"] # Appears ok here
print str(userConstraints) # Has extra DPs here. Why? How to fix?

输出:

0.8
{'test': 0.080000000000000002}

序列化逻辑(另一边)

obj=ast.literal_eval(theSerialisedString)

序列化对象的输出

{'test': 0.080000000000000002}

因此,总而言之,您的 Python 版本和实现对于 floating-point 数字具有非常精确的 repr()。 (我们可以看出它不是香草 CPython 2.7.7,因为 the shorter floating-point repr() from Python 3.1 has been backported into CPython 2.7.0,而且那个版本不像你说的那样做 reprs。)

您的序列化有线格式是 Python repr(),您希望将其中一些冗长的浮点数四舍五入,因为某些原因。

没问题,因为 Python 附带 reprlib - a module for customizing repr (confusingly repr in Python 2)。

瞧瞧:

import repr as reprlib  # Python 2
import reprlib          # Python 3


class TruncatedFloatRepr(reprlib.Repr):
    def repr_float(self, x, level):
        v = repr(x)
        if "." in v:
            decimals_after_dot = len(v.partition(".")[-1])
            if decimals_after_dot > 5:  # Too many decimals? Truncate!
                return "%.2f" % x
        # Otherwise, use the vanilla `repr`.
        return v


userConstraints = {
    "test": 0.08000000004,
    "hello": ["world", "beep", 3.0, "boop"],
    "one": ("two", 1.1),
}

print(TruncatedFloatRepr().repr(userConstraints))

输出为

{'hello': ['world', 'beep', 3.0, 'boop'], 'one': ('two', 1.1), 'test': 0.08}

当然,您可能会考虑将 5 更改为其他内容,或者计算小数部分中零的个数,或者任何适合您的业务逻辑的想法。 实际上,此实现总是会截断小数点精度过高的数字,这可能不是您真正想要的。