How do I check if a string is a number (float)?

后端 未结 30 3982
暗喜
暗喜 2020-11-21 05:16

What is the best possible way to check if a string can be represented as a number in Python?

The function I currently have right now is:

def is_numb         


        
30条回答
  •  春和景丽
    2020-11-21 05:52

    For strings of non-numbers, try: except: is actually slower than regular expressions. For strings of valid numbers, regex is slower. So, the appropriate method depends on your input.

    If you find that you are in a performance bind, you can use a new third-party module called fastnumbers that provides a function called isfloat. Full disclosure, I am the author. I have included its results in the timings below.


    from __future__ import print_function
    import timeit
    
    prep_base = '''\
    x = 'invalid'
    y = '5402'
    z = '4.754e3'
    '''
    
    prep_try_method = '''\
    def is_number_try(val):
        try:
            float(val)
            return True
        except ValueError:
            return False
    
    '''
    
    prep_re_method = '''\
    import re
    float_match = re.compile(r'[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?$').match
    def is_number_re(val):
        return bool(float_match(val))
    
    '''
    
    fn_method = '''\
    from fastnumbers import isfloat
    
    '''
    
    print('Try with non-number strings', timeit.timeit('is_number_try(x)',
        prep_base + prep_try_method), 'seconds')
    print('Try with integer strings', timeit.timeit('is_number_try(y)',
        prep_base + prep_try_method), 'seconds')
    print('Try with float strings', timeit.timeit('is_number_try(z)',
        prep_base + prep_try_method), 'seconds')
    print()
    print('Regex with non-number strings', timeit.timeit('is_number_re(x)',
        prep_base + prep_re_method), 'seconds')
    print('Regex with integer strings', timeit.timeit('is_number_re(y)',
        prep_base + prep_re_method), 'seconds')
    print('Regex with float strings', timeit.timeit('is_number_re(z)',
        prep_base + prep_re_method), 'seconds')
    print()
    print('fastnumbers with non-number strings', timeit.timeit('isfloat(x)',
        prep_base + 'from fastnumbers import isfloat'), 'seconds')
    print('fastnumbers with integer strings', timeit.timeit('isfloat(y)',
        prep_base + 'from fastnumbers import isfloat'), 'seconds')
    print('fastnumbers with float strings', timeit.timeit('isfloat(z)',
        prep_base + 'from fastnumbers import isfloat'), 'seconds')
    print()
    

    Try with non-number strings 2.39108395576 seconds
    Try with integer strings 0.375686168671 seconds
    Try with float strings 0.369210958481 seconds
    
    Regex with non-number strings 0.748660802841 seconds
    Regex with integer strings 1.02021503448 seconds
    Regex with float strings 1.08564686775 seconds
    
    fastnumbers with non-number strings 0.174362897873 seconds
    fastnumbers with integer strings 0.179651021957 seconds
    fastnumbers with float strings 0.20222902298 seconds
    

    As you can see

    • try: except: was fast for numeric input but very slow for an invalid input
    • regex is very efficient when the input is invalid
    • fastnumbers wins in both cases

提交回复
热议问题