Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to keep the column order using csv.DictReader?

Tags:

python

csv

For example, my csv has columns as below:

ID, ID2, Date, Job No, Code 

I need to write the columns back in the same order. The dict jumbles the order immediately, so I believe it's more of a problem with the reader.

like image 994
Alex Avatar asked Dec 11 '09 01:12

Alex


People also ask

Is DictReader ordered?

DictReader s are now OrderedDict s, not regular ones as they were previously (so doing something like this is no longer necessary). The good news, I guess, is that using this approach won't hurt, it'll only be redundant. @martineau in Python 3.8, the rows returned from csv. DictReaders are changed to dict.

What is the difference between csv reader and csv DictReader?

csv. Reader() allows you to access CSV data using indexes and is ideal for simple CSV files. csv. DictReader() on the other hand is friendlier and easy to use, especially when working with large CSV files.


1 Answers

Python's dicts do NOT maintain order prior to 3.6 (but, regardless, in that version the csv.DictReader class was modified to return OrderedDicts).

However, the instance of csv.DictReader that you're using (after you've read the first row!-) does have a .fieldnames list of strings, which IS in order.

So,

for rowdict in myReader:   print ['%s:%s' % (f, rowdict[f]) for f in myReader.fieldnames] 

will show you that the order is indeed maintained (in .fieldnames of course, NEVER in the dict -- that's intrinsically impossible in Python!-).

So, suppose you want to read a.csv and write b.csv with the same column order. Using plain reader and writer is too easy, so you want to use the Dict varieties instead;-). Well, one way is...:

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's headers     dh = dict((h, h) for h in ra.fieldnames)     wb.fieldnames = ra.fieldnames     wb.writerow(dh)    wb.writerow(d)  b.close() a.close() 

assuming you have headers in a.csv (otherewise you can't use a DictReader on it) and want just the same headers in b.csv.

like image 90
Alex Martelli Avatar answered Sep 20 '22 14:09

Alex Martelli