您好我是Python编程的新手,似乎无法解决这个问题。
我有一个包含100个子文件夹的目录,每个文件夹中都有一个文本文件(没有文件扩展名),所有文件都完全相同。每个文件包含一列不同长度的数字。
我想将每个文件的所有数字合并到一个csv文件中,每个文件中的数字都在不同的列中。
所以我应该得到一个包含100列不同长度数字的矩阵,其中每列对应一个文件。
文件示例:
文件1
1
15
23
22
10
文件2
3
55
22
我有这个脚本:
# import modules
import glob
import csv
import sys
import itertools
inf = glob.glob("*/*-ambig")
for f in inf:
with open(f) as fin:
with open(sys.argv[1], 'w') as fout:
writer = csv.writer(fout, delimiter=',', quotechar='', quoting=csv.QUOTE_NONE)
headers = ('coverage', )
writer.writerow(headers)
for line in fin:
columns = line.split("\n") # split each column on new line
writer.writerow(itertools.izip_longest(*columns, fillvalue=['']))
但是我收到了这个错误:
Traceback (most recent call last):
File "coverage_per_strain.py", line 21, in <module>
writer.writerow(itertools.izip_longest(*columns, fillvalue=['']))
_csv.Error: sequence expected
有没有人知道我的代码有什么问题?你能看到其他任何错误吗?
谢谢!
答案 0 :(得分:0)
csv.writerow
期望序列作为参数。 itertools.izip_longest
正在返回一个迭代器。因此错误信息。
您应该可以通过以下方式解决问题:
writer.writerow(list(itertools.izip_longest(*columns, fillvalue=[''])))
答案 1 :(得分:0)
这是我在意识到您使用Python 2.7之前编写的解决方案。这只能用Python 3.3+编写,因为它使用非常漂亮的contextlib.ExitStack
上下文管理器,它只在该版本中添加(我也使用Python 3的map
):
import glob
import csv
import sys
import contextlib
from itertools import zip_longest
in_filenames = glob.glob("*/*-ambig")
with contextlib.ExitStack() as stack:
in_files = [stack.enter_context(open(filename)) for filename in in_filenames]
out_file = stack.enter_context(open(sys.argv[1], "w", newlines=""))
writer = csv.writer(out_file, delimiter=',', quoting=csv.QUOTE_NONE)
writer.writerow(('coverage',)) # do you want the header repeated for each column?
writer.writerows(zip_longest(*(map(str.strip, f) for f in in_files), fillvalue=""))
这是我尝试将其移植回Python 2.我没有测试过这个版本。我使用try
/ finally
对来处理文件的关闭(和imap
来处理剥离而不先将所有文件都读入内存中):
import glob
import csv
import sys
from itertools import izip_longest, imap
in_filenames = glob.glob("*/*-ambig")
with open(sys.argv[1], "wb") as out_file:
in_files = []
try:
for filename in in_filenames:
in_files.append(open(filename))
writer = csv.writer(out_file, delimiter=',', quoting=csv.QUOTE_NONE)
writer.writerow(('coverage',))
writer.writerows(izip_longest(*[imap(str.strip, f) for f in in_files],
fillvalue=""))
finally:
for f in in_files:
try:
f.close()
except: # ignore exceptions here, or the later files might not get closed!
pass