I would like to implement a function round(num, min, max)
that rounds a float to at least min
decimal places and at most max
. I want it to return a string. I have something that works, but it was surprisingly long. Can you write something more pythonic than me?
Usage
round(3.14159, 2, 4) --> '3.1416'
round(3.14159, 0, 2) --> '3.14'
round(3.14159, 0, 1) --> '3.1'
round(3.14159, 0, 0) --> '3'
round(3.14159, 4, 6) --> '3.141590'
round(3.14, 4, 6) --> '3.1400'
round(3, 4, 6) --> '3.0000'
I think you get the idea. Here's what I've got.
def normalize(amount, min=0, max=2):
"""
Rounds to a variable number of decimal places - as few as necessary in the range [min,max]
:param amount: A float, int, decimal.Decimal, or string.
:param min: the minimum number of decimal places to keep
:param max: the maximum number of decimal places to keep
:return: string.
"""
if not amount:
return amount
# To Decimal, round to highest desired precision
d = round(Decimal(amount), max)
s = str(d)
# Truncate as many extra zeros as we are allowed to
for i in range(max-min):
if s[-1] == '0':
s = s[:-1]
# Lose a trailing decimal point.
if s[-1] == '.':
s = s[:-1]
return s
You're confusing float rounding with print formatting. *
The float 3.14
is a different number than 3.1415
. So rounding 3.1415
to 2 digits makes sense.
But the float 3.00
is the exact same number as 3.0
. So rounding 3.0
to 2 digits isn't going to do anything; it's still going to be the same thing you started with.
Meanwhile, if you want to change the way numbers are printed out, you can do that using the format
function, the str.format
method, f-strings, %
formatting, etc. For example:
>>> pi = 3.1415
>>> indianapi = round(pi, 0)
>>> indianapi
3.0
>>> f'{indianapi:.3f}'
'3.000'
See Format Specification Mini-Language for details on how to use f-strings (and str.format
and format
), and printf
-Style String Formatting for details on how to use %
.
* Either that, or you're expecting floats to keep track of their precision and preserve it through a chain of operations. If that's what you're after, floats can't do that, but decimal.Decimal
can, so you may want to look at the decimal
module. But I don't think that's what you want here.
Just some small improvements, but keeping the basic idea (convert value, strip zeroes, strip trailing decimal point).
First change is to avoid name clash with builtin functions min
and max
. I think that using functions designed for the particular purpose ( str.format
for value formatting, str.rstrip
for stripping from right, str.endswith
for testing the last character) makes it little bit more pythonic.
def round(amount, dmin, dmax):
assert 0 <= dmin <= dmax
astr = '{:.{prec}f}'.format(amount, prec=dmax)
if dmax != dmin:
astr = astr[:dmin-dmax] + astr[dmin-dmax:].rstrip('0')
if astr.endswith('.'):
astr = astr[:-1]
return astr
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.