格式化Python中的浮点数而没有多余的零
如何格式化浮点数,使其不包含剩余的零? 换句话说,我希望得到的字符串尽可能短..?
喜欢:
3 -> "3"
3. -> "3"
3.0 -> "3"
3.1 -> "3.1"
3.14 -> "3.14"
3.140 -> "3.14"
14个解决方案
145 votes
我,我会做('%f' % x).rstrip('0').rstrip('.') - 保证定点格式而不是科学记谱法等等。是的,不像%g那样光滑和优雅,但是,它有效(我不知道如何强制%g永远不要使用 科学计数法;-)。
Alex Martelli answered 2019-05-27T18:43:43Z
119 votes
您可以使用g来实现此目的:
'%g'%(3.140)
或者,对于Python 2.6或更高版本:
'{0:g}'.format(3.140)
来自g的文档:g导致(除其他外)
无效的尾随零[将] 从有效数字中删除,然后删除 如果有,小数点也被删除 没有剩下的数字跟随它。
unutbu answered 2019-05-27T18:44:27Z
9 votes
在查看几个类似问题的答案之后,这对我来说似乎是最好的解决方案:
def floatToString(inputValue):
return ('%.15f' % inputValue).rstrip('0').rstrip('.')
我的推理:
Decimal.normalize()没有摆脱科学记数法。
>>> '%g' % 0.000035
'3.5e-05'
15个小数位似乎可以避免奇怪的行为,并且对我的需求有很大的精确度。
>>> ('%.15f' % 1.35).rstrip('0').rstrip('.')
'1.35'
>>> ('%.16f' % 1.35).rstrip('0').rstrip('.')
'1.3500000000000001'
我本来可以用Decimal.normalize()而不是float,但这有点慢(~30%)。
我本可以使用Decimal.normalize(),但这也有一些问题。 首先,它慢了很多(~11x)。 我还发现虽然它具有非常高的精度,但在使用float时仍然会出现精度损失。
>>> Decimal('0.21000000000000000000000000006').normalize()
Decimal('0.2100000000000000000000000001')
>>> Decimal('0.21000000000000000000000000006')
Decimal('0.21000000000000000000000000006')
最重要的是,我仍然会从float转换为Decimal.normalize(),这可能会让你最终得到的东西不是你放在那里的数字。 我认为当算术停留在Decimal并且Decimal用字符串初始化时,Decimal效果最好。
>>> Decimal(1.35)
Decimal('1.350000000000000088817841970012523233890533447265625')
>>> Decimal('1.35')
Decimal('1.35')
我确定Decimal.normalize()的精度问题可以根据需要使用上下文设置进行调整,但考虑到已经很慢的速度并且不需要荒谬的精度以及我仍然会从浮点转换并失去精度的事实,我 不认为值得追求。
我不关心可能的“-0”结果,因为-0.0是一个有效的浮点数,无论如何它可能是罕见的,但是既然你提到你想要保持字符串结果尽可能短,你 总是可以在非常小的额外速度成本下使用额外的条件。
def floatToString(inputValue):
result = ('%.15f' % inputValue).rstrip('0').rstrip('.')
return '0' if result == '-0' else result
PolyMesh answered 2019-05-27T18:45:50Z
9 votes
尝试最简单,最有效的方法怎么样?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()
Ander answered 2019-05-27T18:46:30Z
3 votes
这是一个适合我的解决方案。 它是PolyMesh的解决方案和使用新的.format()语法的混合体。
for num in 3, 3., 3.0, 3.1, 3.14, 3.140:
print('{0:.2f}'.format(num).rstrip('0').rstrip('.'))
输出:
3
3
3
3.1
3.14
3.14
Kaushal Modi answered 2019-05-27T18:46:58Z
2 votes
你可以简单地使用format()来实现这个目的:
format(3.140, '.10g')其中10是您想要的精度。
clel answered 2019-05-27T18:47:30Z
1 votes
>>> str(a if a % 1 else int(a))
Shameem answered 2019-05-27T18:47:49Z
1 votes
虽然格式化很可能是大多数Pythonic方式,这里是使用more_itertools工具的替代解决方案。
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"
该数字将转换为字符串,该字符串将删除满足谓词的尾随字符。 函数定义more_itertools不是必需的,但它用于测试断言,这些断言全部通过。 注意:它适用于字符串输入并接受可选谓词。
另请参阅此第三方库的详细信息,more_itertools。
pylang answered 2019-05-27T18:48:30Z
1 votes
如果您可以使用3.和3.0显示为“3.0”,这是一种非常简单的方法,可以从浮动表示中剥离零:
print("%s"%3.140)
(感谢@ellimilial指出例外情况)
drevicko answered 2019-05-27T18:49:03Z
0 votes
使用宽度足够大的%g,例如'%.99g'。对于任何相当大的数字,它将以定点表示法打印。
编辑:它不起作用
>>> '%.99g' % 0.0000001
'9.99999999999999954748111825886258685613938723690807819366455078125e-08'
alexanderlukanin13 answered 2019-05-27T18:49:36Z
0 votes
OP希望删除超级零,并使得结果字符串尽可能短。
我发现%g指数格式化会缩短非常大和非常小的值的结果字符串。 问题出现在不需要指数表示法的值上,例如128.0,它既不是非常大也不是非常小。
这是将数字格式化为短字符串的一种方法,仅当Decimal.normalize创建太长的字符串时才使用%g指数表示法。 这可能不是最快的解决方案(因为它确实使用了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']
kinok answered 2019-05-27T18:50:16Z
0 votes
对于浮动你可以使用这个:
def format_float(num):
return ('%i' if num == int(num) else '%s') % num
测试一下:
>>> format_float(1.00000)
'1'
>>> format_float(1.1234567890000000000)
'1.123456789'
对于Decimal,请在此处查看解决方案:[https://stackoverflow.com/a/42668598/5917543]
Artem Skoretskiy answered 2019-05-27T18:50:56Z
-1 votes
你可以使用print(max(int(x), x))这样:
print(max(int(x), x))
elig answered 2019-05-27T18:51:28Z
-3 votes
你可以用大多数pythonic方式实现这一点:
python3:
"{:0.0f}".format(num)
Lan Vukušič answered 2019-05-27T18:52:01Z