开发者

How to convert list of strings to their correct Python types?

Given a list of python strings, how can I automatically convert them to their correct type?

Meaning, if I have:

["hello", "3", "3.64", &q开发者_开发百科uot;-1"]

I'd like this to be converted to the list

["hello", 3, 3.64, -1]  

where the first element is a string, the second an int, the third a float, and the fourth an int.

How can I do this?


import ast

L = ["hello", "3", "3.64", "-1"]

def tryeval(val):
  try:
    val = ast.literal_eval(val)
  except ValueError:
    pass
  return val

print [tryeval(x) for x in L]


Without using evaluation:

def convert(val):
    constructors = [int, float, str]
    for c in constructors:
        try:
            return c(val)
        except ValueError:
            pass


I accomplished the same using json.loads method

def f(l):
    for i in l:
        try:
            yield json.loads(i)
        except:
            yield i

Test:

In [40]: l
Out[40]: ['hello', '3', '3.64', '-1']

In [41]: list(f(l))
Out[41]: ['hello', 3, 3.64, -1]


def tryEval(s):
  try:
    return eval(s, {}, {})
  except:
    return s

map(tryEval, ["hello", "3", "3.64", "-1"])

Only do this if you trust the input. Also, be aware that it supports more than just literals; arithmetic expressions will be evaluated as well.


If the you are truly interested in only strings, floats, and ints, I prefer the more verbose, less-evalful

def interpret_constant(c):
    try:
        if str(int(c)) == c: return int(c)
    except ValueError:
        pass
    try:
        if str(float(c)) == c: return float(c)
    except ValueError:
        return c

test_list = ["hello", "3", "3.64", "-1"]

typed_list = [interpret_constant(x) for x in test_list]
print typed_list
print [type(x) for x in typed_list]


This is not really an answer, but I wanted to point out how important this can be when you have a database of parameters with schema ID, PAR, VAL. For instance:

ID  PAR      VAL
001 velocity '123.45'
001 name     'my_name'
001 date     '18-dec-1978'

This schema is appropriate when you don't know how many parameters you need to store for a certain ID. The disadvantage is precisely that the values in VAL are all strings, and need to be converted to the correct data type on demand. You can do this by adding a fourth column to the schema, called TYPE, or you can use any of the approaches proposed thus far.

Good question!

PS. The database schema is related to one of my previous questions.


A variant of ryans's nice solution, for numpy users:

def tonum( x ):
    """ -> int(x) / float(x) / None / x as is """
    if np.isscalar(x):  # np.int8 np.float32 ...
    # if isinstance( x, (int, long, float) ):
        return x
    try:
        return int( x, 0 )  # 0: "0xhex" too
    except ValueError:
        try:
            return float( x )  # strings nan, inf and -inf too
        except ValueError:
            if x == "None":
                return None
            return x

def numsplit( line, sep=None ):
    """ line -> [nums or strings ...] """
    return map( tonum, line.split( sep ))  # sep None: whitespace
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜