Convert a csv.DictReader object to a list of dictionaries?
Asked Answered
R

5

40

A csv file names.csv has content:

first_name last_name
Baked Beans
Lovely Spam
Wonderful Spam

I would like to read it into a list of dictionaries, with the first row containing the keys:

>>> import csv
>>> with open('names.csv') as csvfile:
...     reader = csv.DictReader(csvfile)
...     for row in reader:
...         print(row['first_name'], row['last_name'])
...
Baked Beans
Lovely Spam
Wonderful Spam

But is the type of reader csv.DictReader? How can I convert reader into a list of dictionaries? Thanks.

Rambler answered 3/4, 2015 at 13:13 Comment(0)
T
53
import csv
with open("in.csv") as csvfile:
    reader = csv.DictReader(csvfile,delimiter=" ")
    print(list(reader))
[{'first_name': 'Baked', 'last_name': 'Beans'}, {'first_name': 'Lovely', 'last_name': 'Spam'}, {'first_name': 'Wonderful', 'last_name': 'Spam'}]

If the delimiter is not actually a , you need to specify " " or whatever it is.

Just to clear any confusion, the code works fine for python3.6 also, the only difference is that using DictReader gives Orderdicts by default:

In [1]: import csv
   ...: with open("in.csv") as csvfile:
   ...:     reader = csv.DictReader(csvfile, delimiter=" ")
   ...:     print(list(reader))
   ...:     
[OrderedDict([('first_name', 'Baked'), ('last_name', 'Beans')]), OrderedDict([('first_name', 'Lovely'), ('last_name', 'Spam')]), OrderedDict([('first_name', 'Wonderful'), ('last_name', 'Spam')])]

You can access keys exactly the same, an OrderedDict just keeps key insertion order:

In [2]: import csv
   ...: with open("in.csv") as csvfile:
   ...:     reader = csv.DictReader(csvfile, delimiter=" ")
   ...:     for dct in reader:
   ...:         print(f"{dct['first_name']} {dct['last_name']}")
   ...:         
   ...:     
Baked Beans
Lovely Spam
Wonderful Spam

Which py3.6 actually does too, so if for some reason you really want a dict:

In [5]: import csv
   ...: with open("in.csv") as csvfile:
   ...:     reader = csv.DictReader(csvfile, delimiter=" ")
   ...:     for dct in map(dict, reader):
   ...:         print(dct)
   ...:         print(f"{dct['first_name']} {dct['last_name']}")
   ...:         
   ...:     
{'first_name': 'Baked', 'last_name': 'Beans'}
Baked Beans
{'first_name': 'Lovely', 'last_name': 'Spam'}
Lovely Spam
{'first_name': 'Wonderful', 'last_name': 'Spam'}
Wonderful Spam

The ordering retention on insertion in py3.6 is an implementation detail and may change, but if enough of us use it, it may just have to stay :)

Thirlage answered 3/4, 2015 at 13:19 Comment(6)
Not correct with Python 3.6, which should use print([dict(d) for d in reader])Occident
@MattFletcher, it works fine in py3.6, what is not working for you? Is it because you see OrderedDict's?Thirlage
Yes, and therefore can't iterate over it properly. I'm not a Python master so I may be missing something massive, but I read that they way it worked had been changed in py3.6 - can't for the life of me find the SO thread...Occident
@MattFletcher, I added a little more to the answer, an OrderDict is, for all intents and purposes a dictionary, it just maintains the insertion order, so for your csv, you would see columns/keys in the same order as they appear in your file.Thirlage
Gotcha. Blame my own stupidity then ;) thanks for clarifying too, I've been banging my head with Dict vs OrderedDict!Occident
@MattFletcher, no worries, for py < 3.6, dict ordering is random, so you needed an OrderedDict specifically, if you wanted to maintain the insertion order.Thirlage
R
26

Use list():

print(list(reader))

Demo:

>>> with open('names.csv') as csvfile:
...     reader = csv.DictReader(csvfile, delimiter=" ")
...     print(list(reader))
... 
[{'first_name': 'Baked', 'last_name': 'Beans'}, {'first_name': 'Lovely', 'last_name': 'Spam'}, {'first_name': 'Wonderful', 'last_name': 'Spam'}]
Romansh answered 3/4, 2015 at 13:17 Comment(2)
What if the csv file has many columns? How will it form dictionary,or listsJuvenescence
@HNSingh The dictionaries within the list will just be longer. In the example above, the only columns are first_name and last_name.Haunted
G
10

Create function

import csv


def csv_to_dict(filename):
    result_list=[]
    with open(filename) as file_obj:
        reader = csv.DictReader(file_obj, delimiter=delimiter)
        for row in reader:
            result_list.append(dict(row))
    return result_list

and use it:

list_of_dicts = csv_to_dict('names.csv')
Guthrey answered 24/4, 2020 at 15:40 Comment(0)
A
6

The csv.DictReader creates a dictreader object as noted in the title. This object is only useable while the file is open and cant be sliced.

To convert the object to a list as per the title....

list_of_dicts = list(your_dictreader_object)
Augment answered 21/5, 2020 at 21:34 Comment(0)
M
0
with open(path_to_file, 'r', newline='') as csvfile:
    reader = csv.DictReader(csvfile)
    dict_item = list(map(dict, reader))
    result = dict((key, dict_item[0][result[key]]) for key in result.keys())
Moron answered 12/2 at 9:59 Comment(1)
This question already has a few answers—including one that has been extensively validated by the community. Are you certain your approach hasn’t been given previously? If so, it would be useful to explain how your approach is different, under what circumstances your approach might be preferred, and/or why you think the previous answers aren’t sufficient. Can you kindly edit your answer to offer an explanation?Literati

© 2022 - 2024 — McMap. All rights reserved.