Например, мои csv имеют столбцы, как показано ниже:
ID, ID2, дата, номер задания, код
Мне нужно записать столбцы в том же порядке. Диктат сразу же перепутал заказ, поэтому я считаю, что это больше проблема с читателем.
Например, мои csv имеют столбцы, как показано ниже:
ID, ID2, дата, номер задания, код
Мне нужно записать столбцы в том же порядке. Диктат сразу же перепутал заказ, поэтому я считаю, что это больше проблема с читателем.
Python dict
НЕ поддерживать порядок до 3.6.
Однако экземпляр csv.DictReader
, который вы используете (после того, как вы прочитали первую строку!), имеет список строк .fieldnames
, который IS по порядку.
Итак,
for rowdict in myReader:
print ['%s:%s' % (f, rowdict[f]) for f in myReader.fieldnames]
покажет вам, что порядок действительно поддерживается (в .fieldnames
, конечно, НИКОГДА в dict
), что по сути невозможно в Python! -).
Итак, предположим, что вы хотите прочитать a.csv
и написать b.csv
с тем же порядком столбцов. Использование простого читателя и писателя слишком просто, поэтому вместо этого вы хотите использовать разновидности Дикта;-). Ну, один из способов...:
import csv
a = open('a.csv', 'r')
b = open('b.csv', 'w')
ra = csv.DictReader(a)
wb = csv.DictWriter(b, None)
for d in ra:
if wb.fieldnames is None:
# initialize and write b headers
dh = dict((h, h) for h in ra.fieldnames)
wb.fieldnames = ra.fieldnames
wb.writerow(dh)
wb.writerow(d)
b.close()
a.close()
Предположим, что у вас есть заголовки в a.csv
(иначе вы не сможете использовать DictReader на нем) и хотите иметь одинаковые заголовки в b.csv
.
from csv import DictReader, DictWriter
with open("input.csv", 'r') as input_file:
reader = DictReader(f=input_file)
with open("output.csv", 'w') as output_file:
writer = DictWriter(f=output_file, fieldnames=reader.fieldnames)
for row in reader:
writer.writerow(row)
Сделайте OrderedDict
из каждой строки dict
, отсортированной по DictReader.fieldnames
.
import csv
from collections import OrderedDict
reader = csv.DictReader(open("file.csv"))
for row in reader:
sorted_row = OrderedDict(sorted(row.items(),
key=lambda item: reader.fieldnames.index(item[0])))
Я знаю, что этот вопрос старый... но если вы используете DictReader
, вы можете передать ему упорядоченный список с именами полей в fieldnames
param
Unfortunatley по умолчанию DictReader не позволяет переопределять класс dict, пользовательский DictReader будет делать трюк, хотя
import csv
class DictReader(csv.DictReader):
def __init__(self, *args, **kwargs):
self.dict_class = kwargs.pop(dict_class, dict)
super(DictReader, self).__init__(*args, **kwargs)
def __next__(self):
''' copied from python source '''
if self.line_num == 0:
# Used only for its side effect.
self.fieldnames
row = next(self.reader)
self.line_num = self.reader.line_num
# unlike the basic reader, we prefer not to return blanks,
# because we will typically wind up with a dict full of None
# values
while row == []:
row = next(self.reader)
# using the customized dict_class
d = self.dict_class(zip(self.fieldnames, row))
lf = len(self.fieldnames)
lr = len(row)
if lf < lr:
d[self.restkey] = row[lf:]
elif lf > lr:
for key in self.fieldnames[lr:]:
d[key] = self.restval
return d
используйте его так
import collections
csv_reader = DictReader(f, dict_class=collections.OrderedDict)
# ...