Read .csv file with columns of varying length as dictionary in Python

Question:

How do I read in a .csv file in Python with columns of varying lengths? I want to create a dictionary from the .csv file, with the .csv columns as lists of dictionary values.

I’ve figured out how to write the dictionary to a .csv file, but I need help reading in that same file.

import csv
import itertools

path = 'C:/Users/.../test.csv'

out_dict = {
    'Class1':       ['A', 'B'],
    'Class2':       ['C', 'D', 'E', 'F', 'G', 'H', 'I'],
    'Class3':       ['J', 'K', 'L', 'M', 'N']}

# write dictionary to csv
with open(path, 'wt',  newline='') as csv_file:
    writer = csv.writer(csv_file)
    writer.writerow(out_dict.keys())
    writer.writerows(itertools.zip_longest(*out_dict.values()))
csv_file.close()        

# read csv as dictionary
with open(path, 'rt') as csv_file:
    reader = csv.reader(csv_file);
    in_dict = ???
csv_file.close()

print(in_dict)

Desired Output:

{'Class1': ['A', 'B'],
 'Class2': ['C', 'D', 'E', 'F', 'G', 'H', 'I'],
 'Class3': ['J', 'K', 'L', 'M', 'N']}
Asked By: rasputin

||

Answers:

To read the CSV file back I recommend to use csv.DictReader:

import csv
import itertools

path = '<PATH>'

out_dict = {
    "Class1": ["A", "B"],
    "Class2": ["C", "D", "E", "F", "G", "H", "I"],
    "Class3": ["J", "K", "L", "M", "N"],
}

# write dictionary to csv
with open(path, 'wt',  newline='') as csv_file:
    writer = csv.writer(csv_file)
    writer.writerow(out_dict.keys())
    writer.writerows(itertools.zip_longest(*out_dict.values()))

# read csv as dictionary
out = {}
with open(path, 'rt') as csv_file:
    reader = csv.DictReader(csv_file)
    for row in reader:
        for k, v in row.items():
            if v != '':
                out.setdefault(k, []).append(v)

print(out)

Prints:

{
    "Class1": ["A", "B"],
    "Class2": ["C", "D", "E", "F", "G", "H", "I"],
    "Class3": ["J", "K", "L", "M", "N"],
}
Answered By: Andrej Kesely

As Andrej said, DictReader is probably the way to go. I came up with a slightly different method:

in_dict = {}

with open('test.csv', 'r') as f:
    reader = csv.DictReader(f)
    for row in reader:
        for key, val in row.items():
            if key not in in_dict.keys():
                in_dict[key] = []
            if row[key]:
                in_dict[key].append(val)
    f.close()

print(in_dict)
Answered By: Jacob Stuligross

You could also use json to write your dict to a file and to later read it.

from pprint import pprint
import json

out_dict = {
    'Class1':       ['A', 'B'],
    'Class2':       ['C', 'D', 'E', 'F', 'G', 'H', 'I'],
    'Class3':       ['J', 'K', 'L', 'M', 'N']}
   
with open('test01.json', 'w') as fout:
    json.dump(out_dict, fout)

with open('test01.json', 'r') as fin:
    in_dict = json.load(fin)

pprint(in_dict)

Prints:

{'Class1': ['A', 'B'],
 'Class2': ['C', 'D', 'E', 'F', 'G', 'H', 'I'],
 'Class3': ['J', 'K', 'L', 'M', 'N']}
Answered By: Chris Charley
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.