解析带有缺少字段的制表符分隔文件

Son*_*nny 4 python csv parsing

这是我正在尝试解析的复杂制表符分隔文件的示例

ENTRY   map0010\tNAME Glycolysis\tDESCRIPTION Glycolysis is the process of converting glucose into pyruvate\tCLASS   Metabolism\tDISEASE   H00071  Hereditary fructose intolerance\tH00072  Pyruvate dehydrogenase complex deficiency\tDBLINKS     GO: 0006096 0006094
ENTRY   map00020\tNAME  Citrate cycle (TCA cycle)\tCLASS   Metabolism; Carbohydrate Metabolism\tDISEASE   H00073  Pyruvate carboxylase deficiency\tDBLINKS     GO: 0006099\tREL_PATHWAY map00010  Glycolysis / Gluconeogenesis\tmap00053  Ascorbate and aldarate metabolism
Run Code Online (Sandbox Code Playgroud)

我正在尝试获取仅包含一些字段的输出,例如:

ENTRY   map0010\tNAME Glycolysis\tCLASS   Metabolism\tDISEASE   H00071  Hereditary fructose intolerance H00072  Pyruvate dehydrogenase complex deficiency\tDBLINKS     GO: 0006096 0006094\tNA
ENTRY   map00020\tNAME  Citrate cycle (TCA cycle)\tCLASS   Metabolism; Carbohydrate Metabolism\tDISEASE   H00073  Pyruvate carboxylase deficiency\tDBLINKS     GO: 0006099\tREL_PATHWAY map00010  Glycolysis / Gluconeogenesis\tmap00053  Ascorbate and aldarate metabolism
Run Code Online (Sandbox Code Playgroud)

主要问题是并非所有行都包含相同数量的字段,因此我需要删除包含字符串"DESCRIPTION"的字段,并在字段"CLASS"所在的行中添加空字段当下.

此外,对于某些字段,数据被分成多个(fi,第1行,DISEASE后面的字段包含疾病数据!),我需要加入它们.

我尝试过:

input = open('file', 'r')

dict = ["ENTRY", "NAME", "CLASS", "DISEASE", "DBLINKS", "REL_PATHWAY"]

split_tab = []
output = []

for line in input:
    split_tab.append(line.split('\t'))

for item in dict:
    for element in split_tab:
        if item in element:
            output.append(element)
        else:
            output.append('\tNA\t')
Run Code Online (Sandbox Code Playgroud)

但它保留了所有内容,而不仅仅是dict中指定的元素.请你帮助我好吗?

Spe*_*bun 6

使用内置的csv库.你的工作会容易得多.

对于一些示例代码:

import csv
reader = csv.reader(open('myfile.csv', 'rb'), dialect='excel-tab')
fieldnames = ['Name','Class']
writer = csv.DictWriter(open('myfile.csv', 'rb'), fieldnames, restval='', extrasaction='ignore', dialect='excel-tab')

for row in reader:
    newrow = {}
    for field in row:
        key = field.split(' ', 1)[0]
        newrow[key] = field
    writer.writerow(newrow)
Run Code Online (Sandbox Code Playgroud)

特别注意DictWriter的设置方式.这是很多,如果你包括易于使用restvalextrasaction领域.它们允许您传递具有比作者期望的更多或更少值的字典.

只需适当设置您的字段名称,并设置阅读器以使用正确的方言.这可能包括添加您自己的,但csv链接有关于如何执行此操作的说明.

编辑

在Rob的评论发布在下面之后,我对此进行了修改,以考虑到csv方言不像我想象的那么强大的事实.