2011-12-08 105 views
3

我从一个文本文件中读取位置记录,为examle,它看起来像这样:迭代字符串格式化/解析?

AB ATEA 000401550 

每个记录被分配字符的具体数量,例如:

Code: AB (characters from 0 - 2) 
Name: ATEA (characters from 3 - 7) 
Value1: 00040 (characters from 8 - 13) 
Value2: 1550 (characters from 13 - 16) 

我有使用循环和元组列表作为记录键&字符位置解析此问题,并将这些记录存储在字典中,如下所示:

alist = [('Code',0,2),('Name',3,7),('Value1',8,13),('Value2',13,16)] 
    adict = {} 
    for x in afile: 
     for a, b, c in alist: 
     adict[a] = x[b:c] 
现在

,问题是,在字典中的值,必须使用一个特定的数据类型的小数&具体数量进行格式化,例如:

Code = X i.e. string 
Name = X i.e. string 
Value1 = 9V9(4) i.e. float with 4 decimals, i.e. 0.0040 
Value2 = 9(2)V9(2) i.e. float with 2 decimals, i.e. 15.50 

所以,我想我可以建立一个函数,它接受记录名称和记录值作为输入,然后,该函数内住它包含记录值的格式的字典,例如:

def converter(name, value): 
     adict = {'Code':'%s' % value, 
       'Name':'%s' % value, 
       'Value1':float('%s.%s' % (value[:1],value[1:])), 
       'Value2':float('%s.%s' % (value[:2],value[2:]))} 
     return adict[name] 

的问题是,当我运行解析循环如下:

alist = [('Code',0,2),('Name',3,7),('Value1',8,13),('Value2',13,16)] 
    adict = {} 
    for x in afile: 
     for a, b, c in alist: 
     adict[a] = converter(a,x[b:c]) 

Python会抛出一个ValueError,因为函数中的值输入是在运行时通过字典中的所有项目传递的,因此,当'AB'被送入“float()”时,字典创建停止并且python抛出错误。

回答

3

您可以为每个项目指定一个转换器:

def float_converter(value): 
    return float('{0}.{1}'.format(value[:1], value[1:])) 

alist = [('Code' , 0 , 2 , None), 
     ('Name' , 3 , 7 , None), 
     ('Value1', 8 , 13, float_converter), 
     ('Value2', 13, 16, float_converter)] 

adict = {} 
for x in afile: 
    for name, start, stop, converter in alist:  
     value = x[start:stop] 
     if converter: 
      value = converter(value) 
     adict[name] = value 

看到它联机工作:ideone

+0

谢谢你马克!我在这里提前道歉。在我的例子中,我没有仔细说明浮点数不总是有相同的小数点,并且逗号并不总是在第一个数字之后。因此,例如,一条记录可能如下所示:030050将其转换为30.050,而另一条记录可能如下所示:0125并将其转换为1.25。这是我的错误,因为没有正确地说明转换的细微差别,但是我确实喜欢你的建议,这促使我稍后发布另一个想法。 – GE420

+0

@ GE420:也许你可以做这样的事情? https://ideone.com/k6Ri0 –

+0

这个新建议真的很聪明!非常感谢你马克!我确实通过在转换器函数内部使用字符串构建字典,然后使用“try”语句返回一个float,或者在“try”引发ValueError异常时返回一个字符串来解决此问题。但是,我不认为这是安全的,所以我将考虑实施您的建议。 – GE420

1

如何:

adict = {} 
for x in afile: 
    adict={ 
     'Code':x[0:2], 
     'Name':x[3:7], 
     'Value1':int(x[8:13])/1e4, 
     'Value2':int(x[13:16])/1e2 
     } 
0
def converter(name, value): 
    if name in ['Value1', 'Value2']: 
     result = float('%s.%s' % (value[:1],value[1:]) 
    else: 
     result = value 
    return result