0

Goal:

(In Python 3.6)

Determine if the string passed to the function should be interpreted as an Int, Float or String. Hopefully (with a builtin Python functions) without needed to write my own function which walks chars in Python.

Basically, like the C atoi() and atoll() functions, if the entire buffer is successfully read.

Should mark as Int:

  • "-1234"
  • "1234"
  • "+1234"

Should mark as Float:

  • "-1.234"
  • "1.234"
  • "+1.234"

Should mark as string:

  • "972-727-9857"
  • "1_2345"
  • "asdf"

Tried:

Using casts:

def find_type(s):
    try:
        int(s)
        return int
    except ValueError:
        pass
    try:
        float(s)
        return float
    except ValueError:
        pass
    return str
 

^ the above has the drawback:

  • "1_234" -> int(1234)

Using AST

import ast

def find_type(s):
    obj_type = ast.literal_eval(s)
    if isinstance(obj_type, float):
        return float
    if isinstance(obj_type, int):
        return int
    return str

^ this also has issues with:

  • "123_123" -> int(123123)
  • "123-123-123" -> int(-123)

Question

Am I just doomed to write my own function which walks chars? ... I am about to just write this in C...

How do I parse a string to a float or int?

^ I found the above, but it doesn't quite solve my problem.

Tim
  • 2,139
  • 13
  • 18

2 Answers2

1

Just check for the underscore:

def find_type(s):
    if '_' in s:
        return str
    for typ in (int,float):
        try:
            typ(s)
            return typ
        except ValueError:
            pass
    return str

trials = '-1234','1234','+1234','-1.234','1.234','+1.234','972-727-9857','1_2345','asdf'

for trial in trials:
    print(trial,find_type(trial))

Output:

-1234 <class 'int'>
1234 <class 'int'>
+1234 <class 'int'>
-1.234 <class 'float'>
1.234 <class 'float'>
+1.234 <class 'float'>
972-727-9857 <class 'str'>
1_2345 <class 'str'>
asdf <class 'str'>
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
0

Hrmm... after posting this question, I thought of this:

With Regex:

import re
int_regex = re.compile(r'^(-|\+)?[0-9]+$')
float_regex = re.compile(r'^(-|\+)?([0-9]+)?\.[0-9]+$')

def find_type(s):
    if re.match(int_regex, s):
        return int
    if re.match(float_regex, s):
        return float
    return str

I guess this is probably the only/best way.

Tim
  • 2,139
  • 13
  • 18