Capt. Crunch
Capt. Crunch

Reputation: 4789

Python3 drop decimal places if not needed

I see lots of answers about formatting floating numbers in Python 3 with a limited number of decimal places, e.g.:

>>> "{:.4f}".format(3.14159265359)
'3.1416'

But this formatting will keep redundant trailing 0's:

>>> "{:.4f}".format(3/4)
'0.7500'

What I'd like to have is to drop the trailing zeroes in a nice way:

>>> "{:.4f??}".format(3/4)
'0.75'

Using the g format seems to get closer to this, but it counts the digits BEFORE the decimal as part of the total field width, e.g.:

>>> "{:.4g}".format(3/4)
'0.75'

is perfect, but:

>>> "{:.4g}".format(3.14159265359)
'3.142'

instead of the desired 3.1416

To clarify, whole numbers (e.g. 0 alone) shouldn't have a decimal at all.

Is this possible with format alone, or do I have to resort to dropping the trailing zeroes through string manipulation on the formatted number?

The documentation page I studied (besides searching the web): https://docs.python.org/3/library/string.html#formatspec

Upvotes: 1

Views: 772

Answers (5)

Vishal Singh
Vishal Singh

Reputation: 62

You can use round function to do this work. round function takes two parameters. First one is the floating number that you want to round off and second one is the number of places after decimal you want.

a=10/3
print(round(a,4))

This will return 3.3333.

a=3/4
print(round(a,4))

This will return 0.75.

Upvotes: 0

ThePyGuy
ThePyGuy

Reputation: 18406

What you are looking for is round, and for that whole number condition, you can use float.is_integer :

def func(x, digits):
    x = round(x, digits)
    return int(x) if float.is_integer(x) else x

SAMPLE RUN

>>> func(3.14159265359, 4)
3.1416
>>> func(3.14000022, 4)
3.14
>>> func(3.000022, 4)
3

PS: You can convert the return values to string type, if needed.

Upvotes: 0

U13-Forward
U13-Forward

Reputation: 71570

I am not sure if this is possible with bare string formatting, but you could do:

>>> a = 3/ 4
>>> "{:.{a}f}".format(a, a=min(len(str(a).split('.')[-1]), 4))
'0.75'
>>> a = 3.14159265359
>>> "{:.{a}f}".format(a, a=min(len(str(a).split('.')[-1]), 4))
'3.1416'
>>> 

Or why not rstrip:

>>> a = 3 / 4
>>> "{:.4f}".format(a).rstrip("0")
'0.75'
>>> a = 3.14159265359
>>> "{:.4f}".format(a).rstrip("0")
'3.1416'
>>> 

Numpy can do this better:

>>> import numpy as np
>>> np.format_float_positional(0.75, 4)
'0.75'
>>> np.format_float_positional(np.pi, 4)
'3.1416'
>>> 

Upvotes: 1

ijc
ijc

Reputation: 494

To convert a float to a string that has at most N digits after the decimal point, but does not include trailing 0's, you can use round() and then convert to a string.

>>> str(round(3.14159265359, 4))
'3.1416'
>>> str(round(3/4, 4))
'0.75'
>>> str(round(17, 4))
'17'

Upvotes: 2

Capt. Crunch
Capt. Crunch

Reputation: 4789

One way I found after posting is:

print('{:.4f}.format(a).rstrip('.0') or '0')

I still wonder if it's possible more elegantly.

Upvotes: 0

Related Questions