Как написать строку заголовка с помощью csv.Диктатор?
предположим, что у меня есть csv.DictReader
объект и я хочу записать его в виде CSV-файла. Как я могу это сделать?
Я знаю, что могу написать строк данных такой:
dr = csv.DictReader(open(f), delimiter='t')
# process my dr object
# ...
# write out object
output = csv.DictWriter(open(f2, 'w'), delimiter='t')
for item in dr:
output.writerow(item)
но как я могу включить поля?
3 ответа:
Edit:
В 2.7 / 3.2 есть новаяwriteheader()
метод. Кроме того, ответ Джона Мэчина предоставляет более простой способ записи строки заголовка.
Простой пример использованияwriteheader()
метод теперь доступен в 2.7 / 3.2: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.
От документация:параметр поля определяет порядок, в котором значения в словарь передали писателю() метод записываются в csvfile.
иными словами, параметр поля является обязательным, поскольку в 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)
вариантов несколько:
(1) кропотливо сделать identity-mapping (т. е. ничего не делать) дикт из ваших имен полей, так что csv.DictWriter может преобразовать его обратно в список и передать его в csv.экземпляр писателя.
(2) в документации упоминается "базовый
writer
инстанции" ... так что просто используйте его (пример в конце).dw.writer.writerow(dw.fieldnames)
(3) Избегайте csv.Диктатор накладные расходы и сделать это самостоятельно с csv.писатель
написание данные:
w.writerow([d[k] for k in fieldnames])
или
w.writerow([d.get(k, restval) for k in fieldnames])
вместо
extrasaction
"функциональность", я бы предпочел закодировать его сам; таким образом, вы можете сообщить обо всех" дополнительных " ключах и значениях, а не только о первом дополнительном ключе. Что является реальной неприятностью с DictWriter является то, что если вы проверили ключи самостоятельно, как каждый дикт был построен, вы должны помнить, чтобы использовать extrasaction= 'игнорировать' в противном случае он будет медленно (fieldnames-это список) повторить проверьте: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' >>>