Is there a concise way of formatting a number, that on occasion can also be a string?
The number would normally be a float, but occasionally it's also denoted as the string "n/a".
I would like to format the float with a fixed number of decimals, but print the entire string in case it is not a number.
For instance:
var=3.145623
print("This is {0:.2f}".format(var))
>>>This is 3.14
,but
var = "n/a"
print("This is {0:.2f}".format(var))
>>> File "<stdin>", line 1, in <module>
>>> ValueError: Unknown format code 'f' for object of type 'str'
I am not surprised by the ValueError, but wonder if there is a concise way around it, ideally without an explicit if-statement.
Indeed, the f
format specifier only works on actual float
values. You can't avoid having to special-case your n/a
value.
You can format the float separately, and conditionally, then interpolate the result into the larger template:
var_formatted = format(var, '.2f') if var != 'n/a' else var
print("This is {0:4}".format(var_formatted))
If you are really averse to if
, you can use exception handling too:
try:
var_formatted = format(var, '.2f')
except ValueError:
var_formatted = 'n/a'
print("This is {0:4}".format(var_formatted))
Another option would be for you to wrap the value in a class with a __format__
method:
class OptionalFloat(object):
def __init__(self, value):
self.value = value
def __format__(self, fmt):
try:
return self.value.__format__(fmt)
except ValueError:
return self.value
print("This is {0:.2f}".format(OptionalFloat(var)))
This moves the requirement to detect the type into another class method, keeping your output code a little cleaner and free of all those pesky conditionals or exception handlers:
>>> var = 3.145623
>>> print("This is {0:.2f}".format(OptionalFloat(var)))
This is 3.15
>>> var = 'n/a'
>>> print("This is {0:.2f}".format(OptionalFloat(var)))
This is n/a
Python supports not-a-number as float('nan')
and it may be more useful than the string "n/a" in your code. It works with formatting and produces more sane results than a string if you use it in computations.
NaN:
>>> n = float('nan')
>>> n
nan
>>> "{0:.2f}".format(n)
'nan'
>>> n == 3
False
>>> n * 2
nan
>>> n < 5
False
String:
>>> n = 'n/a'
>>> "{0:.2f}".format(n)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Unknown format code 'f' for object of type 'str'
>>> n == 3
False
>>> n * 2
'n/an/a'
>>> n < 5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: str() < int()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With