在下面的示例中,我想格式化为小数点后 1 位,但 python 似乎喜欢将数字四舍五入,有没有办法让它不四舍五入?
>>> '{:.1%}'.format(0.9995)
'100.0%'
>>> '{:.2%}'.format(0.9995)
'99.95%'
在下面的示例中,我想格式化为小数点后 1 位,但 python 似乎喜欢将数字四舍五入,有没有办法让它不四舍五入?
>>> '{:.1%}'.format(0.9995)
'100.0%'
>>> '{:.2%}'.format(0.9995)
'99.95%'
如果您想始终向下舍入(而不是四舍五入到最接近的精度),请使用以下math.floor()
函数明确地这样做:
from math import floor
def floored_percentage(val, digits):
val *= 10 ** (digits + 2)
return '{1:.{0}f}%'.format(digits, floor(val) / 10 ** digits)
print floored_percentage(0.995, 1)
演示:
>>> from math import floor
>>> def floored_percentage(val, digits):
... val *= 10 ** (digits + 2)
... return '{1:.{0}f}%'.format(digits, floor(val) / 10 ** digits)
...
>>> floored_percentage(0.995, 1)
'99.5%'
>>> floored_percentage(0.995, 2)
'99.50%'
>>> floored_percentage(0.99987, 2)
'99.98%'
像这样的东西:
def my_format(num, x):
return str(num*100)[:4 + (x-1)] + '%'
>>> my_format(.9995, 1)
'99.9%'
>>> my_format(.9995, 2)
'99.95%'
>>> my_format(.9999, 1)
'99.9%'
>>> my_format(0.99987, 2)
'99.98%'
在 Python 3.6+ 中,您可以使用格式化的字符串文字,也称为 f 字符串。这些比str.format
. 此外,您可以使用更有效的楼层划分来代替math.floor
. 在我看来,语法也更具可读性。
两种方法都包含在下面以进行比较。
from math import floor
from random import random
def floored_percentage(val, digits):
val *= 10 ** (digits + 2)
return '{1:.{0}f}%'.format(digits, floor(val) / 10 ** digits)
def floored_percentage_jpp(val, digits):
val *= 10 ** (digits + 2)
return f'{val // digits / 10 ** digits:.{digits}f}%'
values = [random() for _ in range(10000)]
%timeit [floored_percentage(x, 1) for x in values] # 35.7 ms per loop
%timeit [floored_percentage_jpp(x, 1) for x in values] # 28.1 ms per loop
有几种方法,也许最简单的是
x = str(10. * 0.9995).split('.')
my_string = '%s.%s%%' % (x[0], x[1][:2])
这将确保您始终将小数点放在正确的位置(对于像1.0000
or之类的边缘情况0.001
)
在使用更现代的 python 3.6+ f-string 格式的同时扩展接受的答案
def floored_percentage(val, digits):
val *= 10 ** (digits + 2)
return f'{floor(val) / 10 ** digits}%)'
没有任何数字(就像我需要的那样),它甚至更简单:
def floored_percentage(val):
return f"{floor(val*100)}%"