2017-08-30 54 views
1

我需要我的程序帮助。 我想阅读我的标签文件,然后添加一个新的列(ab)到该文件,我想从字典中获得(hi)。在tabfile中插入字典

我的词典被命名为hi,对于我想要的数据列ab。 数据应该像字典中那样位于正确的special_name旁边。请看看我的例子。

我的标签文件看起来像:

Names names_id first second special_name 
lili  1   a  b  Tm 
Katrin 2   c  d  Tm 
Paul  3   e  f  ui 
bob  4   g  h  zb 
tina  5   i  j  ac 

它应该看起来像:

Names names_id first second special_name ab 
lili  1   a  b Tm   a 
Katrin 2   c  d Tm   a 
Paul  3   e  f ui   f 
bob  4   g  h zb   b 
tina  5   i  j ac   a 

我的脚本如下:

with open("myData.tab","r") as file: 
     hi = {'ac':{'ab': 'a', 'po':'pb'}, 
      'Tm':{'ab': 'a', 'po':'h'}, 
      'ui':{'ab': 'b', 'po':'h'}, 
      'zb':{'ab': 'f', 'po':'j'}} 
     for line in file: 
      line = line.strip() 
      columns = line.split("\t") 
      print(line) 
       for row in columns: 
        file.append('ab') 

当我打印,我得到的整个数据,但没有标题和没有字典。我会很感激任何帮助。

+0

我看不到你在哪里打印它 - 你确定这是整个[mcve]? –

+0

我只做了打印(线)。我测试了它是否能够提供整个数据。 – Fox

+0

请同时添加一个标签文件的例子,以及它之后的样子。 –

回答

0

以下代码在您的问题中提供所需的输出。 然而,与原始帖子进行比较时需要考虑一些事项。

with open('myData.tab.tab','r') as input_file: 
    hi = {'ac':{'ab': 'a', 'po':'pb'}, 
      'Tm':{'ab': 'a', 'po':'h'}, 
      'ui':{'ab': 'b', 'po':'h'}, 
      'zb':{'ab': 'f', 'po':'j'}} 
    columns=[] 
    for line in input_file: 
     line = line.strip() 
     columns.append(line.split('\t')) 
    output_list = [columns[0]+['ab']] 
    for row in columns[1:]: 
     row.append(hi[row[-1]]['ab']) 
     output_list.append(row) 


with open('myData.tab2.tab','w') as output_file: 
    for row in output_list: 
     output_file.write("\t".join(row)+'\n') 

与您的原始文章相比,文件仍然打开相同。字典仍然创建相同我只将文件对象名称从file更改为input_file

在此代码中创建了一个名为columns的空列表。之后,我们遍历文件中的每一行,与您在代码中执行的操作非常相似。唯一的区别是我们将每行添加到columns列表中。

在循环遍历文件中的每一行后,我们创建一个output_list,向其中添加第一行(带有标题的行),并将'ab'字符串添加到标题栏。

然后我们循环遍历非标题行的每一行以及与特殊名称对应的hi字典中的值到每一行。然后我们将该行添加到output_list。 然后我们打开一个不同的文件,并从我们的ouput_list中的每一行写入它。产生这个输出(结果是制表符分隔只有在SO上的间隔很小)。

Names names_id first second special_name ab 
lili 1 a b Tm a 
Katrin 2 c d Tm a 
Paul 3 e f ui b 
bob 4 g h zb f 
tina 5 i j ac a 

注意几件事:此代码会给你一个KeyError如果您有任何的special_name列下的值没有出现在你的字典hi。为了简单起见,我选择了最容易理解的实现。但它是vulnarable到KeyError

您不必到output_list写入到一个单独的文件,您可以更改myData2.tabmyData.tab然而,这将彻底重写了该文件。如果出现任何问题,您可能会丢失原始文件。所以我个人的偏好是(如果可能)写入一个新文件。这样你永远不会失去原始输入。

+0

非常感谢。现在我明白如何去做。 – Fox

0

我会建议你使用Python的csv库这样做,因为它会让事情变得更加容易:

import csv 

hi = { 'ac':{'ab': 'a', 'po':'pb'}, 
     'Tm':{'ab': 'a', 'po':'h'}, 
     'ui':{'ab': 'b', 'po':'h'}, 
     'zb':{'ab': 'f', 'po':'j'}} 

with open('myData.tab', 'rb') as f_input, open('myData output.tab', 'wb') as f_output: 
    csv_input = csv.reader(f_input, delimiter='\t') 
    csv_output = csv.writer(f_output, delimiter='\t') 

    # Copy over the header to the output file and add the new column 
    csv_output.writerow(next(csv_input) + ['ab'])  

    for row in csv_input: 
     row.append(hi[row[4]]['ab']) 
     csv_output.writerow(row) 

给你一个制表符分隔的输出文件,用您的标题正确地从你的输入csv文件复制:

Names names_id first second special_name ab 
lili 1   a  b  Tm    a 
Katrin 2   c  d  Tm    a 
Paul 3   e  f  ui    b 
bob  4   g  h  zb    f 
tina 5   i  j  ac    a 

csv库能够自动读取文件中的每一行,并正确地将其转换成一个列表。当回写一个文件时,你所需要做的就是给它一个列表,它会自动在每个值之间添加必要的分隔符。当你需要处理可能包含分隔符本身的字符串时,这变得更加重要。

+0

谢谢。这也是一个好主意 – Fox