How to skip trailing zeroes from decimal in Python's f-strings?

Viewed 1392

I want to set a precision in my f-strings, but I do not want the the trailing zeroes in the decimal part.

i = 1002
print(f'{i/1000:.2f}') # 1.00 but this must be 1

i = 1009
print(f'{i/1000:.2f}') # 1.01, this is correct

The first print must be 1, my expected behavior is seen in the second print where it is 1.01.

I tried :g but it works for the first print but fails for the second.

i = 1000
print(f'{i/1000:.2g}') # 1, this is correct but
i = 1009
print(f'{i/1000:.2g}') # 1, but this must be 1.01

One way I tried is f'{i/1000:.2f}'.strip('.0') but I wanted to know if there is a better way.

Edit :

In my actual code if i is 100000 then the denominator will also be 100000 (smallest digit in the order of i) in other words the denominator in my code will always be such that the i//denominator will always yield a single digit.

3 Answers

If your string is going to have just floating number, then you can use str.rstrip() (instead of str.strip() which you have right now). Also, you need to make a chained call to it firstly with '0' and then with '.' like .rstrip('0').rstrip('.') to handle the integers with trailing zeros like 10000.

However, if you can have other characters in your string, and you want to strip 0 just for numbers, then you can use nested f-string as:

>>> f"{f'{1002/1000:.2f}'.rstrip('0').rstrip('.')} number"
'1 number'

>>> f"{f'{1009/1000:.2f}'.rstrip('0').rstrip('.')} number"
'1.01 number'

>>> f"{f'{1000:.2f}'.rstrip('0').rstrip('.')} number"
'1000 number'

You'll have to work with two different format strings and round to detect when to use them:

for i in [1002, 1009]:
    print(f'{i/1000:.0f}') if round(i/1000, 2) == 1.00 else print(f'{i/1000:.2f}')

Which yields:

1
1.01

Refer to the Format Specification Mini-Language

The precision is a decimal number indicating how many digits should be displayed after the decimal point for a floating point value formatted with 'f' and 'F', or before and after the decimal point for a floating point value formatted with 'g' or 'G'.

Depends on your matter of taste whether to use the round approach I suggest or the strip approach you're mentioning. If you're understanding Pythonic in the way that code should be clear, concise and maintainable then I'd use the round approach with the two format strings as it's very readable/understandable for future developers.

When not supplying a format specifier, it appears that the formatter automatically simplifies. As such if one rounds the value before asking to format automatically, it gets closer to the desired result. It's not exactly what you asked for, but is simpler than the other answers. (I found my way to this question looking for this behaviour).

i = 1002
print(f'{round(i/1000, 2)}')  # 1.0

i = 1009
print(f'{round(i/1000, 2)}')  # 1.01

Demonstrated:

>>> i = 1002
>>> f'{round(i/1000,2)}'
'1.0'
>>> i = 1009
>>> f'{round(i/1000,2)}'
'1.01'

We can get what you actually wanted by leveraging your original idea / others' answers (only needing to provision for the whole-number cases):

i = 1002
print(f'{round(i/1000, 2)}'.rstrip('.0'))  # 1

i = 1009
print(f'{round(i/1000, 2)}'.rstrip('.0'))  # 1.01

Demonstrated:

>>> i = 1002
>>> f'{round(i/1000, 2)}'.rstrip('.0')
'1'
>>> i = 1009
>>> f'{round(i/1000, 2)}'.rstrip('.0')
'1.01'
Related