ben
ben

Reputation: 21

CSV to Nested Python Dict

i'd like to import certain columns in this csv into a nested python dict:

Name, Type, ID, Job, Height
Adam, Man, asmith, factory, 5
Ben, Man, bjones, mine, 6
Jamie, Woman, jbarnes, bank, 5.5

output:

dict1 = { asmith: {Name:Adam, Type:Man, Height:5},
          bjones, {Name:Ben, Type:Man, Height:6},
          jbarnes:, {Name:Jamie,Type:Woman, Height:5.5} }

Upvotes: 0

Views: 98

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477641

We can use the DictReader from csv for this:

from csv import DictReader

with open('data.csv') as csvfile:
    reader = DictReader(csvfile)
    result = {row[' ID'] : row for row in reader}

Now result will be a dictionary that maps IDs to dictionaries. The dictionary will contain the 'ID' as well. Now result will be:

{' bjones': {'Name': 'Ben', ' Type': ' Man', ' Height': ' 6', ' ID': ' bjones', ' Job': ' mine'}, ' jbarnes': {'Name': 'Jamie', ' Type': ' Woman', ' Height': ' 5.5', ' ID': ' jbarnes', ' Job': ' bank'}, ' asmith': {'Name': 'Adam', ' Type': ' Man', ' Height': ' 5', ' ID': ' asmith', ' Job': ' factory'}}

As we can see the values are not stripped: these contain spaces on the left and the right. We can process these as follows:

from csv import DictReader

with open('data.csv') as csvfile:
    reader = DictReader(csvfile)
    result = {}
    for row in reader:
        row = {k.strip():v.strip() for k,v in row.items()}
        result[row.pop('ID')] = row

This will remove the ID key from the dictionaries as well. Now the answer is:

>>> result
{'jbarnes': {'Name': 'Jamie', 'Height': '5.5', 'Job': 'bank', 'Type': 'Woman'}, 'bjones': {'Name': 'Ben', 'Height': '6', 'Job': 'mine', 'Type': 'Man'}, 'asmith': {'Name': 'Adam', 'Height': '5', 'Job': 'factory', 'Type': 'Man'}}

EDIT: In case you want to ignore the first line, you can call next(..) on the file handler first:

from csv import DictReader

with open('data.csv') as csvfile:
    next(csvfile)
    reader = DictReader(csvfile)
    result = {}
    for row in reader:
        row = {k.strip():v.strip() for k,v in row.items()}
        result[row.pop('ID')] = row

Upvotes: 1

Related Questions