我如何格式化一个浮点数,使它不包含尾随零?换句话说,我希望得到的字符串尽可能短。

例如:

3 -> "3"
3. -> "3"
3.0 -> "3"
3.1 -> "3.1"
3.14 -> "3.14"
3.140 -> "3.14"

当前回答

虽然格式化可能是最python的方式,但这里有一个使用more_itertools的替代解决方案。rstrip工具。

import more_itertools as mit


def fmt(num, pred=None):
    iterable = str(num)
    predicate = pred if pred is not None else lambda x: x in {".", "0"}
    return "".join(mit.rstrip(iterable, predicate))


assert fmt(3) == "3"
assert fmt(3.) == "3"
assert fmt(3.0) == "3"
assert fmt(3.1) == "3.1"
assert fmt(3.14) == "3.14"
assert fmt(3.140) == "3.14"
assert fmt(3.14000) == "3.14"
assert fmt("3,0", pred=lambda x: x in set(",0")) == "3"

数字被转换为字符串,该字符串去掉了满足谓词的尾随字符。函数定义fmt不是必需的,但是这里用它来测试断言,断言都通过了。注意:它适用于字符串输入并接受可选谓词。

另请参阅第三方库more_itertools的详细信息。

其他回答

你可以使用%g来实现:

'%g'%(3.140)

或者,Python≥2.6:

'{0:g}'.format(3.140)

或者,Python≥3.6:

f'{3.140:g}'

格式:g cause (among other things)

不重要的后面的零[是] 从意义上移除,和 如果有,小数点也会被移除 后面没有剩余数字。

试试最简单、可能也是最有效的方法怎么样? normalize()方法删除所有最右边的尾随零。

from decimal import Decimal

print (Decimal('0.001000').normalize())
# Result: 0.001

适用于Python 2和Python 3。

——更新——

正如@BobStein-VisiBone指出的那样,唯一的问题是,像10,100,1000这样的数字……将以指数形式显示。使用下面的函数可以很容易地解决这个问题:

from decimal import Decimal


def format_float(f):
    d = Decimal(str(f));
    return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize()
>>> str(a if a % 1 else int(a))

OP希望删除多余的零,并使生成的字符串尽可能短。

我发现%g指数格式缩短了非常大和非常小的值的结果字符串。问题出现在不需要指数符号的值上,比如128.0,它既不是很大也不是很小。

这里有一种将数字格式化为短字符串的方法,仅在Decimal时使用%g指数表示法。Normalize创建的字符串太长。这可能不是最快的解决方案(因为它使用Decimal.normalize)

def floatToString (inputValue, precision = 3):
    rc = str(Decimal(inputValue).normalize())
    if 'E' in rc or len(rc) > 5:
        rc = '{0:.{1}g}'.format(inputValue, precision)        
    return rc

inputs = [128.0, 32768.0, 65536, 65536 * 2, 31.5, 1.000, 10.0]

outputs = [floatToString(i) for i in inputs]

print(outputs)

# ['128', '32768', '65536', '1.31e+05', '31.5', '1', '10']

我呢,我会用('%f' % x).rstrip('0').rstrip('.')——保证定点格式,而不是科学符号,等等。是的,不像%g那么流畅和优雅,但是,它是有效的(而且我不知道如何强迫%g永远不使用科学符号;-)。