Search code examples
pythoncsvdictionarydefaultdict

Nesting a default dictionary within a default dictionary


I am attempting to read a csv formatted as such

Number,Letter,Color,
1,a,blue,
1,b,green,
1,c,yellow, 

and get out a nested dictionary like this

{
"1":[
    "Letter":["a","b","c"],
    "Color":["blue","green","yellow"]
    ]
}

I can get the Number and its associated rows in from the csv but as soon as I try and nest i get AttributeError: 'collections.defaultdict' object has no attribute 'append', I think im mostly off to the right start

result = co.defaultdict(lambda: co.defaultdict(list))
subresult = co.defaultdict(list)

with open(os.path.join(inputdir,tablelist[i])) as f:

    csv_reader = csv.reader(f)
    csv_headings = next(csv_reader)
    read = csv.DictReader(f, fieldnames=csv_headings)

    for line in read:
        subresult = {}
        for j in range(1,len(csv_headings)):
            #result[line[csv_headings[0]]].append(line[csv_headings[j]])
            result[line[csv_headings[0]]].append(subresult[csv_headings[j]].append(line[csv_headings[j]]))    

Solution

  • Getting rid of the header line in your file, this works:

    from collections import defaultdict
    d = defaultdict(lambda : defaultdict(list))
    with open('myFile.txt', 'r') as f:
        for line in f:
            r = line.strip().split(",")
            number, letter, color = r[:3] 
            d[number]['Letter'].append(letter)
            d[number]['Color'].append(color)
    
    print d
    

    Output

    defaultdict(<function <lambda> at 0x7f3d99f49b90>, {'1': defaultdict(<type 'list'>, 
    {'Color': ['blue', 'green', 'yellow'], 'Letter': ['a', 'b', 'c']})})