我正在尝试编写将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'>]
我正在寻找区分名义和数字属性的方法吗?
答案 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)
如果性能在这里很重要,我会尝试采用三步法。这种方法不必要地避免将字符串强制转换为int
或float
,然后使用对第一个字符的简单检查来失败。
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,那么这可能需要更多时间,因此可能会更快一点。