Heavy
Heavy

Reputation: 1900

How to save list of dicts as CSV and keep keys in order?

I have a list of dicts and need to save them as CSV. The first line would be header listing field names.

Fields order should be the same as in header. The problem is that some fields are optional and some dicts don't contain them. Other problem is that python don't iterate dict keys in order they are defined.

import csv
import sys

fields = ['first_name', 'last_name', 'city']

dicts = [
    {
        "first_name": "John",
        "last_name": "Doe",
        "city": "New York",
    },
    {
        "first_name": "Agent",
        "last_name": "Smith",
        "city": "Matrix",
    },
]

csv_writer = csv.writer(sys.stdout)

csv_writer.writerow(fields)

for obj in dicts:
    # fields order mismatch
    csv_writer.writerow(obj.values())

This would produce CSV rows that don't match header.

first_name, last_name, city
New York,   John,      Doe
Matrix,     Agent,     Smith

I could manually sort fields and check for missing items, but I'm wondering if there is a better solution to output dict values into CSV in predefined order?

Upvotes: 1

Views: 228

Answers (2)

alex2007v
alex2007v

Reputation: 1300

Use DictWriter (also you have a typo in fieldnames list: fisrt_name instead of first_name):

import csv
import sys

fieldnames = ['first_name', 'last_name', 'city']

dicts = [
    {
        "first_name": "John",
        "last_name": "Doe",
        "city": "New York",
    },
    {
        "first_name": "Agent",
        "last_name": "Smith",
        "city": "Matrix",
    },
]
writer = csv.DictWriter(sys.stdout, fieldnames=fieldnames)

writer.writeheader()
for row in dicts:
    writer.writerow(row)

Upvotes: 3

Darren Christopher
Darren Christopher

Reputation: 4811

The accepted answer is great that it utilizes python standard library csv. I'm just putting my answer here (using pandas approach) in case it may help someone.

In [12]: import pandas as pd

In [13]: dicts = [ 
    ...:     { 
    ...:         "first_name": "John", 
    ...:         "last_name": "Doe", 
    ...:         "city": "New York", 
    ...:     }, 
    ...:     { 
    ...:         "first_name": "Agent", 
    ...:         "last_name": "Smith", 
    ...:         "city": "Matrix", 
    ...:     }, 
    ...: ]                                                                                                                                                                                                         

In [14]: df = pd.DataFrame(dicts)                                                                                                                                                                                  

In [15]: df                                                                                                                                                                                                        
Out[15]: 
  first_name last_name      city
0       John       Doe  New York
1      Agent     Smith    Matrix

In [16]: df.to_csv("/path/to/save", index=False) # if you want to save

Hope this helps.

Upvotes: 1

Related Questions