Python string.format() percentage without rounding
If you want to round down always (instead of rounding to the nearest precision), then do so, explicitly, with the math.floor()
function:
from math import floordef floored_percentage(val, digits): val *= 10 ** (digits + 2) return '{1:.{0}f}%'.format(digits, floor(val) / 10 ** digits)print floored_percentage(0.995, 1)
Demo:
>>> 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%'
Something like this:
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%'
With Python 3.6+, you can use formatted string literals, also known as f-strings. These are more efficient than str.format
. In addition, you can use more efficient floor division instead of math.floor
. In my opinion, the syntax is also more readable.
Both methods are included below for comparison.
from math import floorfrom random import randomdef 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