2017-02-12 116 views
1

我已經有一個使用CSV編寫器從列表創建的CSV文件。我想將通過for循環創建的另一個列表追加到CSV文件中。如何將新列表附加到現有的CSV文件?

第一代碼來創建CSV文件如下:

with open("output.csv", "wb") as f: 
    writer = csv.writer(f) 
    for row in zip(master_lst): 
     writer.writerow(row) 

我使用列表master_lst創建的CSV文件,並輸出如下:

read 
ACACCUGGGCUCUCCGGGUACC 
ACGGCUACCUUCACUGCCACCC 
AGGCAGUGUGGUUAGCUGGUUG 

然後,我創建另一個列表(ind_lst)到for循環,並且列表的內容必須以列爲單位附加到上一步中創建的CSV文件。我用下面的代碼:

with open("output.csv", "ab") as f: 
    writer = csv.writer(f) 
    for row in zip(ind_lst): 
     writer.writerow(row) 

我獲得的輸出如下所示:

read 
ACACCUGGGCUCUCCGGGUACC 
ACGGCUACCUUCACUGCCACCC 
AGGCAGUGUGGUUAGCUGGUUG 
sample1 
3 
3 
1 
sample2 
4 
4 
1 

但是我所需要的輸出縱列如下:

read       sample1  sample2 
ACACCUGGGCUCUCCGGGUACC   3   4 
ACGGCUACCUUCACUGCCACCC   3   4 
AGGCAGUGUGGUUAGCUGGUUG   1   1 

我檢查解決方案,但我可以找到明智的追加行的解決方案,但我需要追加列:append new row to old csv file python

我用writer.writerows代替writer.writerow但我得到這個錯誤:

_csv.Error: sequence expected 

輸出結果如下:

read 
ACACCUGGGCUCUCCGGGUACC 
ACGGCUACCUUCACUGCCACCC 
AGGCAGUGUGGUUAGCUGGUUG 
s      a m p l e 1 

正如你可以看到,它打印列表的第一個元素在每個單元和此後終止並出現錯誤。我是python的初學者,所以如果有人能幫助解決這個問題,那真是太棒了。

編輯:

的master_lst是使用下面的代碼創建:

infile= open(sys.argv[1], "r") 
lines = infile.readlines()[1:] 
master_lst = ["read"] 
for line in lines: 
    line= line.strip().split(',') 
    fourth_field = line [3] 
    master_lst.append(fourth_field) 

的ind_lst是使用下面的代碼創建:

for file in files: 
ind_lst = [] 
if file.endswith('.fa'): 
    first = file.split(".") 
    first_field = first [0] 
    ind_lst.append(first_field) 
    fasta= open(file) 
    individual_dict= {} 
    for line in fasta: 
    line= line.strip() 
    if line == '': 
    continue 
    if line.startswith('>'): 
    header = line.lstrip('>') 
    individual_dict[header]= '' 
    else: 
    individual_dict[header] += line 
for i in master_lst[1:]: 
    a = 0 
    if key in individual_dict.keys(): 
    a = individual_dict[key] 
    else: 
    a = 0 
    ind_lst.append(a) 
+0

請[編輯]你的問題,並添加定義'master_iist'代碼,更重要的是,'for'循環,創建' ind_lst'。 – martineau

+0

@martineau:你好,馬蒂諾,我已經更新了你所要求的信息 – rex

+0

@martineau:我正在查看答案部分,並且錯過了你的評論。很抱歉,我沒有明確解釋我的問題:(在當前工作目錄中爲每個文件擴展名爲.fa的文件創建了ind_lst,並且ind_lst的內容必須以列爲單位附加到輸出CSV文件中。 fa文件被讀取,ind_lst被創建並且被添加到列。在這個例子中,我提供了2個.fa文件,用於創建ind_lst到for循環,這個文件必須以列方式添加。請讓我知道你是否有任何問題,如果我的問題仍然不清楚 – rex

回答

1

你實際上是想多列追加到現有的文件,即使這些新字段中的數據全部存儲在一個單子。以不同方式安排ind_lst中的數據可能會更好。但既然你沒有展示過如何完成,下面的代碼就可以在你的問題中使用格式。

由於修改CSV文件是棘手的,因爲他們真的只是文本文件,它會更容易簡單地創建與合併數據的新文件,然後重命名文件後與原始刪除原來的(您現在已被警告)。

import csv 
from itertools import izip # Python 2 
import os 
import tempfile 

master_lst = [ 
    'read', 
    'ACACCUGGGCUCUCCGGGUACC', 
    'ACGGCUACCUUCACUGCCACCC', 
    'AGGCAGUGUGGUUAGCUGGUUG' 
] 

ind_lst = [ 
    'sample1', 
    '3', 
    '3', 
    '1', 
    'sample2', 
    '4', 
    '4', 
    '1' 
] 

csv_filename = 'output.csv' 

def grouper(n, iterable): 
    's -> (s0,s1,...sn-1), (sn,sn+1,...s2n-1), (s2n,s2n+1,...s3n-1), ...' 
    return izip(*[iter(iterable)]*n) 

# first create file to update 
with open(csv_filename, 'wb') as f: 
    writer = csv.writer(f) 
    writer.writerows(((row,) for row in master_lst)) 

# Rearrange ind_lst so it's a list of pairs of values. 
# The number of resulting pairs should be equal to length of the master_lst. 
# Result for example data: [('sample1', 'sample2'), ('3', '4'), ('3', '4'), ('1', '1')] 
new_cols = (zip(*grouper(len(master_lst), ind_lst))) 
assert len(new_cols) == len(master_lst) 

with open(csv_filename, 'rb') as fin, tempfile.NamedTemporaryFile('r+b') as temp_file: 
    reader = csv.reader(fin) 
    writer = csv.writer(temp_file) 
    nc = iter(new_cols) 
    for row in reader: 
     row.extend(next(nc)) # add new columns to each row 
     writer.writerow(row) 
    else: # for loop completed, replace original file with temp file 
     fin.close() 
     os.remove(csv_filename) 
     temp_file.flush() # flush the internal file buffer 
     os.fsync(temp_file.fileno()) # force writing of all data in temp file to disk 
     os.rename(temp_file.name, csv_filename) 

print('done') 

內容文件的創建後,然後更新:

read,sample1,sample2 
ACACCUGGGCUCUCCGGGUACC,3,4 
ACGGCUACCUUCACUGCCACCC,3,4 
AGGCAGUGUGGUUAGCUGGUUG,1,1 
0

您需要將數據從read結合,sample1sample2成行。

假設這些都是iterables,你可以使用zip把它們混合起來:

for row in zip(read, sample1, sample2): 
    writer.writerow(row) 
+0

我猜測,樣本1和樣本2是不可迭代的。樣本1和樣本2是通過for循環創建的列表。爲了適應要創建和追加的新列表,列表ind_lst應該在每個for循環後變爲空。這個問題還有其他解決方案嗎? – rex

+0

@rex不可以。如果你需要多列,你將*有*作爲一行的迭代。 –

相關問題