我需要解析一个具有以下格式的文本表:
-----------------------------------------
| Serial | Name | marks |
| Number |First | Middle | Last | |
-----------------------------------------
| 1 | john | s | doe | 56 |
| 2 | jim | d | bill| 60 |
解析表后,输出应该是一个嵌套字典,数据为列表。
TableData = {'Serial Number':[1,2],
'Name': {'First':[john, jim]}
{'Middle':[s, d]}
{'Last':[doe, bill]}
'marks': [56, 60]
}
截至目前,我有逻辑来获取分隔符(|)的位置,我可以在分隔符之间提取文本。
posList = [[0,9,32,40],[0,9,16,25,32]]
nameList = [['Serial','Name','marks'],['Number ','First','Middle','Last',' ']]
但是我很难将其转换为嵌套字典结构。
答案 0 :(得分:4)
如果您知道数据结构应该是什么样的,那么您不能忘记前3行并从其余行中提取数据吗?例如,假设表位于文本文件table_file
中,那么
table_data = {'Serial Number':[],
'Name':{'First': [],
'Middle': []
'Last': []},
'Marks': []}
with open(table_file, 'r') as table:
# skip first 3 rows
for _ in range(3):
table.next()
for row in table:
row = row.strip('\n').split('|')
values = [r.strip() for r in row if r != '']
assert len(values) == 5
table_data['Serial Number'].append(int(values[0]))
table_data['Name']['First'].append(values[1])
table_data['Name']['Middle'].append(values[2])
table_data['Name']['Last'].append(values[3])
table_data['Marks'].append(values[4])
修改强>
要构造table_data字典,请考虑以下伪代码。公平的警告,我测试了它,它似乎适用于你的例子,应该适用于任何有两行标题的东西。但是,它很草率,因为我在大约10分钟内写道。但是,它可以是一个可以开始改进和扩展的良好开端。这也假设您有用于提取pos_list
和name_list
的代码。
for itertools import tee, izip
def pairwise(iterable):
a, b = tee(iterable)
next(b, None)
return izip(a, b)
def create_table_dict(pos_list, name_list):
intervals = []
for sub_list in pos_list:
intervals.append(list(pairwise(sub_list)))
items = []
for interval, name in zip(intervals, name_list):
items.append([ (i, n) for i, n in zip(interval, name) ])
names = []
for int1, name1 in items[0]:
past_names = []
for int2, name2 in items[1]:
if int1[0] == int2[0]:
if int1[1] == int2[1]:
names.append(' '.join((name1, name2)).strip())
elif int2[1] < int1[1]:
past_names.append(name2)
elif int1[0] < int2[0]:
if int2[1] < int1[1]:
past_names.append(name2)
elif int1[1] == int2[1]:
names.append('{0}:{1}'.format(name1,
','.join(past_names + [name2])))
table = {}
for name in names:
if ':' not in name:
table[name] = []
else:
upper, nested = name.split(':')
nested = nested.split(',')
table[upper] = {}
for n in nested:
table[upper][n] = []
print table