我想在一行中将字符串列表转换为正确的类型(即int,float,boolean等)并解压缩值。
是否有一个内置模块可以比以下更好地完成这个?:
strLst = ["a", "1.0", "2", "True"]
a, b, c, d = [[s[0], float(s[1]), int(s[2]), bool(s[3])] for s in [strLst]][0]
编辑:
我正在从一个大文本文件中创建一个,b,c,d,我希望有一种优雅的方法可以在一行上进行转换。这不仅仅是这个具体示例的问题,而是一个关于可以完成这样的事情的模块的问题:
with open("file.txt") as f:
a, b, c, d = [[s[0], float(s[1]), int(s[2]), bool(s[3])] \
for s in [next(f)[:-1].split()]][0]
根据Niclas Nilsson的评论我可以做以下事情:
a,b,c,d = [ast.literal_eval(s) for s in next(f)[:-1].split()]
答案 0 :(得分:4)
压缩和应用强制转换函数很有效,并且比literal_eval快得多。
此外,如果字符串值不包含引号,则literal_eval会引发“ValueError:malformed string”,这取决于您的数据,可能会出现问题。
from StringIO import StringIO
from time import time
import ast
def zip_test():
# Using StringIO to illustrate using something file-like.
for row in StringIO('a 1.0 2 True\n' * 32):
(a, b, c, d) = [f(v) for (f, v) in zip(
(str, float, int, lambda v: v == 'True'), row.split())]
def ast_test():
for row in StringIO('"a" 1.0 2 True\n' * 32):
(a, b, c, d) = [ast.literal_eval(s) for s in row.split()]
for f in (zip_test, ast_test):
start = time()
for i in range(100):
f()
print '%s: %s' % (f.func_name, time() - start)
# [ ** Results ** ]
#
# zip_test: 0.0131301879883
# ast_test: 0.0835828781128
答案 1 :(得分:1)
我知道问题太旧了。但我的第一个问题是为什么它必须是一个单行程?我的意思是,即使解决方案需要100行,你总是可以将它们放在一个函数下并在其他地方调用函数,所以解决方案将是单行的吗?
如果速度有必要的话,我确实提出了一个比建议更快更简单的双线路。
for row in StringIO('a 1.0 2 True\n' * 32):# Took the idea from derek's answer
(a, b, c, d) = row.split(" ", 3)
b, c, d = float(b), int(c), 'True' in d
正如我所提到的,如果不能使用,你肯定需要一个单行,你可以做这样的事情:
def string_to_multiple_type_list(data):
multi_list = []
for line in data.split("\n"):
a, b, c, d = line.split(" ", 3)
multi_list.append([a, float(b), int(c), 'True' in d])
return multi_list
无论何时需要转换后的值,您都可以将其称为单行:
new_multi_list = string_to_multiple_type_list(data)
即使函数调用需要一点时间(绝对是微秒),它比使用zip更快更优雅。
借用derek的测试代码,我可以看到使用这个用户定义的功能减少20%的时间,并且在两个衬垫的情况下减少30%的时间。