Преобразование списка строк python в их тип

учитывая список строк python, как я могу автоматически преобразовать их в их правильный тип? Значение, если у меня есть:

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

Я хотел бы, чтобы это было преобразовано в список

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

где первый элемент является помехой, второй - int, третий - float, а четвертый - int.

как я могу это сделать? спасибо.

Ответ 1

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]

Ответ 2

Без использования оценки:

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

Ответ 3

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

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

Делайте это только в том случае, если вы доверяете вводам. Кроме того, имейте в виду, что он поддерживает больше, чем просто литералы; арифметические выражения будут также оценены.

Ответ 4

Я выполнил то же самое с помощью метода json.loads

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

Тест:

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

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

Ответ 5

Если вас действительно интересуют только строки, float и ints, я предпочитаю более подробные, менее обоснованные

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]

Ответ 6

На самом деле это не ответ, но я хотел бы указать, насколько это важно, когда у вас есть база данных параметров со схемой ID, PAR, VAL. Например:

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

Эта схема подходит, если вы не знаете, сколько параметров необходимо хранить для определенного ID. Недостатком является то, что значения в VAL являются целыми и должны быть преобразованы в правильный тип данных по требованию. Вы можете сделать это, добавив четвертый столбец в схему, называемый TYPE, или вы можете использовать любой из предложенных до сих пор подходов.

Хороший вопрос!

PS. Схема базы данных связана с одним из моих предыдущих вопросов.

Ответ 7

Вариант красивого решения ryans, для пользователей numpy:

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