如何找到数组的类型

时间:2013-01-06 05:32:18

标签: python arrays csv arff

我正在尝试编写将CSV转换为ARFF的代码。我将每个","之间的值导入到数组的单元格中,例如:

之类的实例
Monday,176,49,203,27,77,38,Second

转换为:

['Monday', '176', '49', '203', '27', '77', '38', 'Second']

问题是Python将每个单元格识别为字符串,您可以通过Python查看已识别的类型:

[<type 'str'>, <type 'str'>, <type 'str'>, <type 'str'>, <type 'str'>, <type 'str'>, <type 'str'>, <type 'str'>]

我正在寻找区分名义和数字属性的方法吗?

3 个答案:

答案 0 :(得分:3)

我能想到的最好的就是这样,使用ast.literal_eval

import ast

def converter(x):
    try:
        val = ast.literal_eval(x)
        return val
    except ValueError:
        return x

给出了

>>> seq = ['Monday', '176', '49', '203', '27', '77', '38', 'Second']
>>> newseq = [converter(x) for x in seq]
>>> newseq
['Monday', 176, 49, 203, 27, 77, 38, 'Second']
>>> map(type, newseq)
[<type 'str'>, <type 'int'>, <type 'int'>, <type 'int'>, <type 'int'>, <type 'int'>, <type 'int'>, <type 'str'>]

使用ast.literal_eval的优势在于它以一种很好的方式处理更多案例:

>>> seq = ['Monday', '12.3', '(1, 2.3)', '[2,"fred"]']
>>> newseq = [converter(x) for x in seq]
>>> newseq
['Monday', 12.3, (1, 2.3), [2, 'fred']]

答案 1 :(得分:2)

for i in lst:
    try:
        int(i)
        #whatever you want to do
    except ValueError:
        #error handling

这样可行,虽然从中可以更好:

for i in lst:
    if i[-1].isdigit():  #it is a number
        #whatever
    else:
        #whatever else

取自here

另请参阅:str.isdigit() method

答案 2 :(得分:1)

如果性能在这里很重要,我会尝试采用三步法。这种方法不必要地避免将字符串强制转换为intfloat,然后使用对第一个字符的简单检查来失败。

  • 对于每个块,检查第一个字符是否为数字
  • 如果是,请先尝试将其解析为int,如果失败,请将其解析为float
  • 如果一切都失败了,那你就有一个大问题:)

类似的东西:

for chunk in chunks:
    if chunk[0].isdigit():
        try:
            return int(chunk)
        except ValueError:
            return float(chunk)
    else:
        # It's a string (a non-numeric entity)
        return chunk

你当然需要在text / csv文件中支持hex / oct文字的更多特殊处理,但我不认为这是正常的情况吗?

编辑:想想看,Volatility使用了类似的方法,唯一的区别是在整个字符串上调用isdigit而不是第一个字符。如果我们有长数字序列,在每个char上调用isdigit,而我的方法总是检查第一个char,那么这可能需要更多时间,因此可能会更快一点。