Answers:
编辑:
在2.7 / 3.2中,有一个新writeheader()
方法。同样,John Machin的答案提供了一种更简单的写标题行的方法。现在使用2.7 / 3.2中提供
的writeheader()
方法的简单示例:
from collections import OrderedDict
ordered_fieldnames = OrderedDict([('field1',None),('field2',None)])
with open(outfile,'wb') as fou:
dw = csv.DictWriter(fou, delimiter='\t', fieldnames=ordered_fieldnames)
dw.writeheader()
# continue on to write data
实例化DictWriter需要一个fieldnames参数。
从文档中:
fieldnames参数标识传递到writerow()方法的字典中的值写入csvfile的顺序。
换句话说,Fieldnames参数是必需的,因为Python字典本质上是无序的。
以下是如何将标头和数据写入文件的示例。
注意:with
声明是在2.6中添加的。如果使用2.5:from __future__ import with_statement
with open(infile,'rb') as fin:
dr = csv.DictReader(fin, delimiter='\t')
# dr.fieldnames contains values from first row of `f`.
with open(outfile,'wb') as fou:
dw = csv.DictWriter(fou, delimiter='\t', fieldnames=dr.fieldnames)
headers = {}
for n in dw.fieldnames:
headers[n] = n
dw.writerow(headers)
for row in dr:
dw.writerow(row)
正如@FM在评论中提到的,您可以将标头编写压缩为单行代码,例如:
with open(outfile,'wb') as fou:
dw = csv.DictWriter(fou, delimiter='\t', fieldnames=dr.fieldnames)
dw.writerow(dict((fn,fn) for fn in dr.fieldnames))
for row in dr:
dw.writerow(row)
dw = csv.DictWriter(fou, delimiter='\t', fieldnames=dr.fieldnames)
。这样,如果您的字段发生更改,则无需调整dictWriter。
一些选择:
(1)费力地在您的字段名称中做出一个身份映射(即不做任何事)命令,以便csv.DictWriter可以将其转换回列表并将其传递给csv.writer实例。
(2)文档中提到了“基础writer
实例”……所以就用它(最后是示例)。
dw.writer.writerow(dw.fieldnames)
(3)避免csv.Dictwriter产生开销,并由csv.writer自己完成
写入数据:
w.writerow([d[k] for k in fieldnames])
要么
w.writerow([d.get(k, restval) for k in fieldnames])
除了extrasaction
“功能”之外,我更愿意自己编写代码。这样,您可以报告所有带有键和值的“附加”,而不仅仅是第一个额外的键。DictWriter真正令人讨厌的是,如果您在构建每个dict时亲自验证了密钥,则需要记住使用extrasaction ='ignore',否则它将缓慢进行(字段名是列表),重复检查:
wrong_fields = [k for k in rowdict if k not in self.fieldnames]
============
>>> f = open('csvtest.csv', 'wb')
>>> import csv
>>> fns = 'foo bar zot'.split()
>>> dw = csv.DictWriter(f, fns, restval='Huh?')
# dw.writefieldnames(fns) -- no such animal
>>> dw.writerow(fns) # no such luck, it can't imagine what to do with a list
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\python26\lib\csv.py", line 144, in writerow
return self.writer.writerow(self._dict_to_list(rowdict))
File "C:\python26\lib\csv.py", line 141, in _dict_to_list
return [rowdict.get(key, self.restval) for key in self.fieldnames]
AttributeError: 'list' object has no attribute 'get'
>>> dir(dw)
['__doc__', '__init__', '__module__', '_dict_to_list', 'extrasaction', 'fieldnam
es', 'restval', 'writer', 'writerow', 'writerows']
# eureka
>>> dw.writer.writerow(dw.fieldnames)
>>> dw.writerow({'foo':'oof'})
>>> f.close()
>>> open('csvtest.csv', 'rb').read()
'foo,bar,zot\r\noof,Huh?,Huh?\r\n'
>>>
extrasaction
功能似乎实现得更好。现在wrong_fields = rowdict.keys() - self.fieldnames so it's effectively a
设置操作。
dw.writerow( dict((f,f) for f in dr.fieldnames) )
。