'Alternative to try/pass - python

    try:
        return float(x)
    except:
        return 0

So this function uses the try except statement but is there an alternative way of doing this??



Solution 1:[1]

Your code looks like it would work but I would always make sure to define the exception you are trying to catch. In this case ValueError
Another way to write this would be

def func(x):
    try:
        y = float(x)
    except ValueError:
        return 0
    # do some more with y if it was changed to a float
    return y

Solution 2:[2]

Assuming x is a str, you could use regex to see if that str is formatted properly to be cast as a float.

import re

float_regex = re.compile(r"^-?(\d*\.)?\d+$")

if float_regex.match(x):
    return float(x)
return 0
  • The ^ ... $ at beginning and end ensure that the match isn't a substring and that the full string can only contain the inner regex. The string must start and stop exactly as defined.
  • -? allows an optional minus sign
  • (\d*\.)? optionally allows a digit followed by a decimal
  • \d+ requires at least 1 digit

See here for more details on the regex expression used: https://regex101.com/r/3RXmM1/1

All of this being said, use your original code, except make sure you only catch the ValueError exception. Using regex is overkill here unless you have a specific reason. If python can't cast as a float then just let it do the work for you.

Solution 3:[3]

Try/except seems like to simplest and best solution, but you could use an if statement similar to this:

if str(x).lstrip('-').replace('.', '', 1).isdigit():
    return float(x)
return 0

The if statement will remove - if it's a negative number and exactly one . from the input and then check there is only digits left. It converts it to a string first so we can use .replace().

There are still possibilities of exceptions like mentioned in the comments if x == '²'

Solution 4:[4]

As @jornsharpe suggested in the comments

from contextlib import suppress
x = "abc"
res= None
with suppress(ValueError):
    res = float(x)
if not isinstance(res, float):
    res = 0
print(res) # 0

But still not a good thind to suppress the Exceptions.

Solution 5:[5]

Your code is fine; using try/catch is promoted among Python coders.

Just as an exercise, I thought I'd follow the definitions in the documentation for the float function and the lexical analysis section on floating point literals. From those we can derive the following regular expression:

import re

reFloat = re.compile(r"(?i)^\s*[+-]?(((\d(_?\d)*)?\.\d(_?\d)*|\d(_?\d)*\.?)(e[+-]?\d(_?\d)*)?|nan|inf(inity)?)\s*$")

We can then define this function:

safeFloat = lambda x, default=0: float(x) if reFloat.match(x) else default

I believe this function will call float if, and only when, float(x) would not raise an exception, provided x is a string.

Some tests:

good = ["-3.14", "10.", ".001", "+1e100", "3.14e-10", "0e0", " 3.14_15_93  ", "+NaN", "  -Infinity\n\f\r\t "]

for x in good:
    print(x.strip(), safeFloat(x))

bad = [".", "_345", "123_", "e13", "123e", "- 1", "5-3", "1e3.4", "Infinit"]

for x in bad:
    print(x.strip(), safeFloat(x))  # Always 0

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Cai Allin
Solution 2 notoriousjere
Solution 3
Solution 4 Deepak Tripathi
Solution 5