【问题标题】:How to append a new list to an existing CSV file?如何将新列表附加到现有 CSV 文件?
【发布时间】:2017-06-30 12:28:47
【问题描述】:

我已经使用 CSV 编写器从列表中创建了一个 CSV 文件。我想将通过 for 循环按列创建的另一个列表附加到 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

然后我通过 for 循环创建另一个列表 (ind_lst),并且列表的内容必须按列附加到上一步中创建的 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)

【问题讨论】:

  • edit 提出您的问题并添加定义master_iist 的代码,更重要的是,添加创建ind_lstfor 循环。
  • @martineau:您好,martineau,我已经更新了您要求的信息
  • @martineau:我正在查看答案部分并错过了您的上述评论。很抱歉,我没有清楚地解释我的问题:( ind_lst 是为当前工作目录中文件扩展名为 .fa 的每个文件创建的,并且 ind_lst 的内容必须按列附加到输出 CSV 文件中。所以所有 . fa 文件被读取,ind_lst 被创建并按列附加。在示例中,我提供了 2 个 .fa 文件,用于通过 for 循环创建 ind_lst,必须按列附加。如果您有任何问题以及我的问题,请告诉我还不清楚
  • 雷克斯:好动作。但是,我厌倦了等待您这样做,并尽我所能从当时的内容中回答了您的问题。您可能可以稍微简化我的答案中的内容 - 重新排列 ind_lst 的部分 - 通过创建 ind_lst 使其成为列表列表,其中每个子列表中的第 n 个元素来自每个 fasta 文件.如果你不知道怎么做,是时候问另一个问题了。
  • 雷克斯:谢谢。 My answer 到一个不相关的问题可能会帮助您从多个同时打开并被读取的 fasta 文件创建 ind_lst(提示提示)。

标签: python csv python-2.x


【解决方案1】:

您需要将readsample1sample2 中的数据组合成一行。

假设这些是可迭代的,您可以使用zip 来组合它们:

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

【讨论】:

  • 我猜样本 1 和样本 2 不可迭代。示例 1 和示例 2 是通过 for 循环创建的列表。列表 ind_lst 应该在每个 for 循环之后变为空,以适应要创建和附加的新列表。这个问题还有其他解决方案吗?
  • @rex 不。如果你想要多列,你将为一行创建一个可迭代的。
【解决方案2】:

您实际上是在尝试将几列附加到现有文件中,即使这些新列的数据都存储在一个列表中。以不同方式排列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

【讨论】:

    猜你喜欢
    • 2016-04-08
    • 2016-11-24
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-13
    • 2020-12-14
    相关资源
    最近更新 更多