我想使用以下格式的python读写文件:
#h -F, field1 field2 field3
a,b,c
d,e,f
# some comments
g,h,i
此文件非常类似于典型的CSV,但以下情况除外:
有什么方法可以使用csv.DictReader()和csv.DictWriter()来读写这些文件吗?
答案 0 :(得分:8)
您可以分别解析第一行以找到分隔符和字段名:
firstline = next(f).split()
delimiter = firstline[1][-1]
fields = firstline[2:]
请注意csv.DictReader
可以将任何iterable作为其第一个参数。因此,要跳过注释,可以将f
包装在只生成非注释行的迭代器(skip_comments
)中:
import csv
def skip_comments(iterable):
for line in iterable:
if not line.startswith('#'):
yield line
with open('data.csv','rb') as f:
firstline = next(f).split()
delimiter = firstline[1][-1]
fields = firstline[2:]
for line in csv.DictReader(skip_comments(f),
delimiter = delimiter, fieldnames = fields):
print line
关于您发布的数据,这会产生
{'field2': 'b', 'field3': 'c', 'field1': 'a'}
{'field2': 'e', 'field3': 'f', 'field1': 'd'}
{'field2': 'h', 'field3': 'i', 'field1': 'g'}
要以此格式编写文件,您可以使用header
辅助函数:
def header(delimiter,fields):
return '#h -F{d} {f}\n'.format(d = delimiter, f=' '.join(fields))
with open('data.csv', 'rb') as f:
with open('output.csv', 'wb') as g:
firstline = next(f).split()
delimiter = firstline[1][-1]
fields = firstline[2:]
writer = csv.DictWriter(g, delimiter = delimiter, fieldnames = fields)
g.write(header(delimiter,fields))
for row in csv.DictReader(skip_comments(f),
delimiter = delimiter, fieldnames = fields):
writer.writerow(row)
g.write('# comment\n')
请注意,您可以使用output.csv
(针对标题或注释行)或g.write
(针对csv)写信至writer.writerow
。
答案 1 :(得分:0)
假设输入文件以input
打开。首先,阅读标题:
header = input.readline()
解析分隔符和字段名称,并使用它来构造DictReader
。现在,代替input
,向读者提供表达式
(ln for ln in input where ln[0] != '#')
跳过评论。