2

我想在一行中将字符串列表转换为正确的类型(即 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]

编辑:

我正在从一个大文本文件创建 a、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()]
4

2 回答 2

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
于 2013-04-27T22:59:50.460 回答
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% 的时间。

于 2013-06-18T09:55:03.550 回答