最优雅的方式在浮点数小数点左侧填充零

1 投票
3 回答
678 浏览
提问于 2025-04-18 08:47

我想要实现的目标

-12.345 -> -012.345

在小数点左边的数字范围是 -999 到 999(这是我特定的需求),而小数点右边可以有任意数量的数字。

我想出了两种方法来实现这个:

def pad(num, pad):
    pad = pow(10,pad)
    if num > 0:
        return "%s" %  str(num + pad)[1:]
    else:
        return "-%s" % str(num - pad)[2:]

def pad(num, pad):
    import math
    mag  = 1 + int(math.log10(abs(num)))
    sz   = len(str(num))
    return str(num).zfill(pad+sz-mag)

但是这在 Python 中看起来有点复杂。我看到之前有类似的问题,但我不太喜欢那个答案……

>>> "%06.2f"%3.3
'003.30'

因为那个答案假设你已经知道小数点在哪里,以及你有多少个小数位。

这似乎是一个常见的情况,所以在 Python 2.7 中有没有更好、更简洁、只用一个函数调用的方法来处理这个问题呢?

3 个回答

0

固定分数与动态分数:

>>> "{:08}".format(-12.345)
'-012.345'

>>> a,b=str(x).split('.');a=int(a);"{}{:03}.{}".format('-' if a<0 else"",abs(a),b)
'-012.345'

整理过的:

def pad(x):
    a, b = str(x).split('.')
    a = int(a)
    return '{}{:03}.{}'.format('-' if a < 0 else ' ', abs(a), b)

for x in [12.0, 12.345, -12.345, -12.3456]:
    print('{:>8} -> {}'.format(x, pad(x)))

输出结果:

    12.0 ->  012.0
  12.345 ->  012.345
 -12.345 -> -012.345
-12.3456 -> -012.3456
2

我觉得你遇到了一个特殊情况。我们可以很简单地指定小数点左边和右边的数字,也可以轻松地指定总的数字个数,但要只指定小数点左边的数字,而完全不管右边的数字,这就比较麻烦了。

我建议最简单的方法是先处理浮点数的小数部分,格式化成整数,然后再处理小数部分,不需要指定长度。

这里有一个经过测试的函数,可以满足你的需求,并且对负数也能正确处理。

import math

def float_lformat(f, width):
    neg = f < 0.0
    fraction, n = math.modf(abs(f)) # get fraction and integer parts of f
    if neg and width > 0:
        width -= 1
    s = "%0*d" % (width, n) + str(fraction)[1:]
    if neg:
        s = '-' + s
    return s
1

不太确定这样做是否符合Python的风格。这只是给整数加上零,然后把小数部分拼接在一起。

def pad(x, p):
    return ('%0'+str(p+(x<0 and 1 or 0))+'d%s') % (x,str(x-int(x))[x<0 and 2 or 1:])

测试

pad(-3,3) -> -003
pad(3,3) -> 003
pad(-3.3,3) -> -003.3
pad(3.3,3) -> 003.3

撰写回答