将 Python Decimal 对象格式化为指定精度

16
我是一名有用的助手,可以为您翻译文本。

我花费了无数小时进行研究、阅读、测试,最终感到困惑和沮丧的是 Python 的 Decimal 对象缺乏最基本的概念:将 Decimal 的输出格式化为字符串。

假设我们有一些具有以下值的字符串或 Decimal 对象:

   0.0008
  11.1111
 222.2222
3333.3333
1234.5678

目标是将十进制数的精度简单地设置为小数点后两位。例如,11.1111将被格式化为11.11,而1234.5678将被格式化为1234.57。我设想的代码类似于以下代码:
import decimal
decimals = [
  decimal.Decimal('0.0008'),
  decimal.Decimal('11.1111'),
  decimal.Decimal('222.2222'),
  decimal.Decimal('3333.3333'),
  decimal.Decimal('1234.5678'),
]
for dec in decimals:
  print dec.as_string(precision=2, rounding=ROUND_HALF_UP)

生成的输出将是:
0.00
11.11
222.22
3333.33
1234.57

显然,我们不能利用十进制上下文的精度,因为这将考虑到所有数字的总数,而不仅仅是小数精度。
我也不感兴趣将 Decimal 转换为 float 来输出其值。Decimal 的整个目的就是避免在浮点数上存储和运行计算。
还有其他解决方案吗?我知道 stack overflow 上有许多类似的问题,但我没有发现它们解决了我所询问的根本问题。
非常感谢!
2个回答

29

只需使用字符串格式化format()函数

>>> for dec in decimals:
...    print format(dec, '7.2f')
... 
   0.00
  11.11
 222.22
3333.33
1234.57

decimal.Decimal 支持与浮点数相同的格式规范, 因此您可以根据需要使用指数、定点、通用、数字或百分比格式。

这是格式化十进制数的官方和Pythonic方法; Decimal 类实现了 .__format__() 方法以高效地处理此类格式。


在处理输出格式或小数精度时,没有内置的十进制接口吗? - Joshua Burns
3
这是用于输出格式的内置界面。 - Martijn Pieters
2
那绝对回答了我的问题,非常感谢!我最担心的是format()在执行实际格式化之前将值转换为浮点数。 - Joshua Burns

2
def d(_in, decimal_places = 3):
    ''' Convert number to Decimal and do rounding, for doing calculations
        Examples:
          46.18271  to   46.183   rounded up
          46.18749  to   46.187   rounded down
          117.34999999999999 to 117.350
         _rescale is a private function, bad practice yet works for now.
    '''
    return Decimal(_in)._rescale(-decimal_places, 'ROUND_HALF_EVEN')

编辑:再次强调,_rescale()不适用于我们普通人,它只能在Python 2.7中使用,不能在3.4版本中使用。


1
在Python中,为什么不能直接比较浮点数和十进制数? - nu everest

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接