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
加载中,请稍侯......
精彩评论