Python equivalent to atoi / atof

后端 未结 6 2044
無奈伤痛
無奈伤痛 2020-12-15 20:48

Python loves raising exceptions, which is usually great. But I\'m facing some strings I desperately want to convert to integers using C\'s atoi / atof semantics - e.g. atoi

相关标签:
6条回答
  • 2020-12-15 21:15

    How about this?

    num=int(q.join(re.findall(r'[\d-]',s)))
    
    0 讨论(0)
  • 2020-12-15 21:17

    It's pretty straightforward to do this with regular expressions:

    >>> import re
    >>> p = re.compile(r'[^\d-]*(-?[\d]+(\.[\d]*)?([eE][+-]?[\d]+)?)')
    >>> def test(seq):
            for s in seq:
                m = p.match(s)
                if m:
                    result = m.groups()[0]
                    if "." in result or "e" in result or "E" in result:
                        print "{0} -> {1}".format(s, float(result))
                    else:
                        print '"{0}" -> {1}'.format(s, int(result))
                else:
                    print s, "no match"
    
    >>> test(s)
    "1 0" -> 1
    "3 of 12" -> 3
    "3 1/2" -> 3
    "3/12" -> 3
    3.15 seconds -> 3.15
    3.0E+102 -> 3e+102
    "what about 2?" -> 2
    "what about -2?" -> -2
    2.10a -> 2.1
    
    0 讨论(0)
  • 2020-12-15 21:21

    I think I will do it char by char:

    def myatof(s):
        try:
            return float(s);
        except:
            last_result = None
            for i in range(1, len(s)):
                try:
                    last_result = float(s[:i])
                except:
                    return last_result
        return last_result
    
    0 讨论(0)
  • 2020-12-15 21:26

    Perhaps use a quick regex to grab only the first part of the string that can be considered numeric? Something like...

    -?[0-9]+(?:\.[0-9]+)?
    

    for floats and for ints just,

    -?[0-9]+
    
    0 讨论(0)
  • If you're so keen on getting exactly the functionality of c's atoi, why not use it directly? E.g., on my Mac,

    >>> import ctypes, ctypes.util
    >>> whereislib = ctypes.util.find_library('c')
    >>> whereislib
    '/usr/lib/libc.dylib'
    >>> clib = ctypes.cdll.LoadLibrary(whereislib)
    >>> clib.atoi('-99foobar')
    -99
    

    In Linux, Windows, etc, identical code should work except that you'll see a different path if you examine whereislib (only on really, really peculiar installations should this code ever fail to find the C runtime library).

    If you're keen on avoiding direct C library usage, I guess you could grab the relevant prefix, e.g. with a RE such as r'\s*([+-]?\d+)', and try int on that.

    0 讨论(0)
  • 2020-12-15 21:28

    I think the iterative version is better than the recursive version

    # Iterative
    def atof(s):
        s,_,_=s.partition(' ') # eg. this helps by trimming off at the first space
        while s:
            try:
                return float(s)
            except:
                s=s[:-1]
        return 0.0
    
    # Recursive
    def atof(s):
        try:
            return float(s)
        except:
            if not s:
                return 0.0
            return atof(s[:-1])
    
    
    print atof("3 of 12")
    print atof("3/12")
    print atof("3 / 12")
    print atof("3.14 seconds")
    print atof("314e-2 seconds")
    print atof("-99 score")
    print atof("hello world")
    
    0 讨论(0)
提交回复
热议问题