2

When I do a simple division in Python 3, such as 123000/1000, I get 123.0, or 4/2 I get 2.0. How do I get rid of the trailing zero in Python 3's division?

EDIT: I don't want just simple integer division. For ex, 1234/1000 should give 1.234. To be clear, this question is about formatting the output, not internal representation.

ItM
  • 301
  • 1
  • 5
  • 16
  • 3
    Possible duplicate of [Python integer division yields float](https://stackoverflow.com/questions/1282945/python-integer-division-yields-float) – modesitt May 03 '19 at 17:18
  • 1
    Why do you need to get rid of the trailing zero? Is it for displaying it or is there some internal reason why you need to get rid of the trailing 0? Maybe we could help with that problem instead – SyntaxVoid May 03 '19 at 17:50
  • Yes, displaying it, as a string. I want to not show the trailing 0 when printing the value as a string, but show the decimal part if it's not just a .0. – ItM May 03 '19 at 17:51

7 Answers7

2

Thanks all for your help! The answer came from @vaultah:

>>> f'{2.1:g}'
'2.1'
>>> f'{2.0:g}'
'2'

So just use regular division such as 4/2 and then format the string. From the docs for 'g': https://docs.python.org/2/library/string.html#format-specification-mini-language "insignificant trailing zeros are removed from the significand, and the decimal point is also removed if there are no remaining digits following it."

ItM
  • 301
  • 1
  • 5
  • 16
  • Would you care to explain how this works? It seems a bit cryptic to me. And how do you apply this to your situation (i.e. when you don't know the numbers beforehand)? – wovano May 03 '19 at 18:28
  • 2
    @Wovano is right, you should explain what is happening. The `g` option is quite obscure but documentation about it can be found here: https://docs.python.org/2/library/string.html#format-specification-mini-language. Scroll down just a bit and you'll find "insignificant trailing zeros are removed from the significand, and the decimal point is also removed if there are no remaining digits following it." – SyntaxVoid May 03 '19 at 19:20
  • @SyntaxVoid, thanks, but actually I was more surprised about the `f'..'` part ;-) Apparently, this a [formatted string literal](https://docs.python.org/3/reference/lexical_analysis.html#f-strings), which is new in Python 3.6. I think the solution should be updated to include that information as well, especially since it won't work for anyone using Python <= 3.5. – wovano May 04 '19 at 09:05
  • 1
    Careful though, for larger numbers this switches to scientific notation: `f"{2000000:g}"` becomes `'2e+06'` – Cerno Mar 09 '23 at 11:09
2

You could use something like this:

def remove_trailing_zeros(x):
    return str(float(x)).rstrip('0').rstrip('.')

remove_trailing_zeros(1.23)  # '1.23'
remove_trailing_zeros(4.0)  # '4
remove_trailing_zeros(1000)  # '1000'

Normally, you would use standard string formatting options like '%2.1f' % number or any of the other many ways to format a string. However, you would then have to specify the amount of digits you want to display but in this case the number of trailing zeros to return is variable. The '%g' format specifier does not have this problem, but uses scientific notation and I don't know if that is what the OP wants.

The above solution converts the number to a "nicely printable string representation" (str(x)), and then removes trailing zeros (.rstrip('0')) and if necessary the remaining trailing period (.rstrip('.')) (to avoid "1." as a result) using standard string methods.

Note: I added the cast to float to make sure the code works correctly for integers as well, in case anyone needs that.

wovano
  • 4,543
  • 5
  • 22
  • 49
  • This is potentially dangerous since if you use this in a function and someone inputs an int, you may change the number in a way you don't want: `str(1000).rstrip('0').rstrip('.')` becomes `1` – Cerno Mar 09 '23 at 11:12
  • 1
    @Cerno, well the question was about formatting *floats*, but I can see your "point" (pun intended :P). I updated the answer so it works with integers as well. Thanks for the feedback. – wovano Mar 09 '23 at 11:42
2

It's "correct" behaviour to have "floats" as a result, and .0 part simply indicates this fact. I think that what matter to you is "representation" of the result in the string. So you should not change actual result and only change the way it's "displayed". Use formatting mini language:

>>> for val in (123000/1000, 4/2, 1234/1000): print(f"{val:g}")  # Use "General format" to represent floats
...                                                                                                                                                                                                                              
123                                                                                                                                                                                                                              
2                                                                                                                                                                                                                                
1.234

imposeren
  • 4,142
  • 1
  • 19
  • 27
1

This works well for me. No scientific notation format for big numbers.

def no_trailing_zero(value: float) -> Union[float, int]:
    return int(value) if value % 1 == 0 else float(str(value))

>>> no_trailing_zero(50)
50
>>> no_trailing_zero(50.11)
50.11
>>> no_trailing_zero(50.1100)
50.11
>>> no_trailing_zero(50.0)
50
>>> no_trailing_zero(500000000.010)
500000000.01
>>>
James H
  • 531
  • 6
  • 15
0

Mod is an O(1) operation which should add almost no overhead to your actual program. You could make it into a one liner also

x = a//b if not a % b else a/b

If you need to do this kind of thing a lot, make it into a function

def func(a, b):
    return a//b if not a % b else a/b
func(10, 2)      # out = 5
func(10, 3)      # out = 3.333333333
func(1200, 100)  # out = 12
func(1234, 1000) # out = 1.234
SyntaxVoid
  • 2,501
  • 2
  • 15
  • 23
  • 1
    If you're really concerned about performance, I would use `divmod()` to avoid doing the division twice. So: `int_result, remainder = divmod(a, b); return a / b if remainder else int_result` – wovano May 04 '19 at 09:43
-1

If you can guarantee that you get just a trailing zero, casting to int gets rid of it:

>>> 4/2
2.0
>>> int(4/2)
2
Luciano
  • 493
  • 5
  • 14
  • I won't know beforehand what number I'm dividing. So having to check a numerator mod denominator == 0 first seems like too much for this. There should be a simpler fix. – ItM May 03 '19 at 17:27
-1
#  // => used for integer output
#   / => used for double output
x = 100/35      # => 2.857142857142857
y = 100//35     # => 2
z = 100.//35    # => 2.0    # floating-point result if divisor or dividend real
Andrew St P
  • 524
  • 1
  • 5
  • 13
  • Although this is a valid explanation of how the division works in Python 3, the question seems to be more about formatting and it was updated with "I don't want just simple integer division", which excludes this solution. – wovano May 04 '19 at 09:34