给定一个令牌列表以及这些令牌的正确的已知类型表示,如何将该类型映射到列表中?如果类型为int
或floats
,我可以在字符串上调用int(x)
以将值转换为int,但如果我的类型为list
,则会失败(或者说numpy.array
)。进行转换的最pythonic方式是什么? eval
不是一个选项,因为数据基本上是未经过清理的。一个例子:
line = "0 0 62.9695 [16.859,-17.1135,46.6351] [7.1759,29.3009,83.1399]"
tokens = line.split()
type_key = [int,int,float,list,list] # Lists do not convert properly here
print [T(x) for T,x in zip(type_key,tokens)]
相关:How to convert a list with multiple types to binary in Python?
答案 0 :(得分:8)
你想要的是ast.literal_eval()
,它是为此目的而设计的。
>>> ast.literal_eval("[16.859,-17.1135,46.6351]")
[16.859, -17.1135, 46.6351]
编辑:根据评论中的问题:
def literal_eval_to_array(literal):
return np.array(ast.literal_eval(literal))
然后你可以在literal_eval_to_array()
中使用type_key
- 记住函数调用和实例化与Python相同。
答案 1 :(得分:1)
我认为最好的方法是为转换器功能创建一个类型的映射,然后你就可以拥有一个复杂的转换器,例如。
import ast
def convert_list(str_val):
return ast.literal_eval(str_val)
def convert_array(str_val):
# do something here
return []
converter_map = {
list: convert_list,
'np.array': convert_array
}
def convert(str_val, _type):
converter = _type
if _type in converter_map:
converter = converter_map[_type]
return converter(str_val)
line = "0 0 62.9695 [16.859,-17.1135,46.6351] [7.1759,29.3009,83.1399]"
type_key = [int,int,float,list,list]
print [convert(v, t) for v, t in zip(line.split(), type_key)]
输出:
[0, 0, 62.969499999999996, [16.859000000000002, -17.113499999999998, 46.635100000000001], [7.1759000000000004, 29.300899999999999, 83.139899999999997]]
这使它成为一个非常灵活的方案,您可以非常灵活地清理和处理输入