在Python中快速转换值为对应数据类型的方法

6 投票
7 回答
2889 浏览
提问于 2025-04-17 01:54

我有一串值,都是字符串。我想把这些值转换成它们对应的数据类型。我手头有值和类型之间的对应关系。

这里有三种不同的数据类型:整数(int)、字符串(str)和日期时间(datetime)。这段代码需要能够处理数据中的错误情况。

我正在做的事情是:

tlist =  [ 'some datetime value', '12', 'string', .... ]

#convert it to: [ datetime object, 12, 'string', ....]

error_data = ['', ' ', '?', ...]

d = { 0: lambda x: datetime.strptime(x,...) if x not in error_data else x, 
      1: lambda x: int(x) if x not in error_data else 0,
      2: lambda x: x 
      ...
     }

result = [ d[i](j) for i, j in enumerate(tlist) ]

要转换的列表非常长,大约有180个值,而且我需要对成千上万这样的列表进行处理。上面的代码性能很差。有没有更快的方法来做到这一点?

谢谢!

7 个回答

2

如果你的日期时间值总是很一致,那为什么不让类型转换来处理你在错误数据中想要管理的无效数据呢?虽然这个方法看起来没有其他一些方案那么吸引人,但它让根据数据在列表中的位置来管理类型转换变得更容易维护和扩展。

def convert(position, val):
    if position == 0:
        try:
            return datetime.strptime(val, '%Y-%m-%d %H:%M:%S') # assuming date is in a constant format
        except ValueError:
            return val
    elif position in (1, 15, 16): # assuming that you have other int values in other "columns"
        try:
            return int(val)
        except ValueError:
            return 0
    else: # string type
       return val

result = [convert(i,j) for i, j in enumerate(tlist)]
2

类似这样的:

>>> values = ["12", "a", "bcd", "2.2"]
>>> types = [int, int, str, float]
>>> defaults = {int: 0, float: 0.0}
>>> res = []
>>> for v, f in itertools.izip(values, types): #Just use zip for Python 3+.
    try:
        res.append(f(v))
    except ValueError:
        res.append(defaults[f])
>>> print(res)
[12, 0, 'bcd', 2.2]

补充:

这个方法不适用于日期时间值。我的解决办法是先用 str 来处理这些值,然后在循环结束后再转换成日期时间格式,像这样:

res[0] = datetime.strptime(res[0], "...")

获取和设置列表中的项目都是 O(1) 的复杂度,所以这应该不是个问题。

0

谢谢大家提供的各种方法。是的,我试过几乎所有提到的方法,但都没有达到我想要的效果。

我尝试了以下方法,效果对我的性能需求来说还不错。这是我做的事情。

  1. 我按照utdemir的建议处理了日期时间值。
  2. 我对所有整数错误值插入了0,代码如下:

    [i] = value if value != '' else 0

  3. 我没有一个一个地用字典来处理值,而是一次性用列表处理所有值。

    def coerce(l):
    return [ l[0], int(l[1]), int(l[2]) ... ]

我的观察:

  1. 单独处理错误情况并一次性处理值帮助很大。
  2. 让代码从异常中恢复需要花费很多时间。
  3. 多次遍历一个列表其实没什么坏处(我就是这样处理错误情况的)。
  4. 举个例子,对于几小时的数据(60万条记录),我的方法把运行时间从6-7分钟缩短到了2分30秒。

撰写回答