How to store CSV data in a Nested Dictionary that has a dictionary and a list?

Refresh

November 2018

Views

436 time

2

I have the following CSV Data,

Rule1,Status1,1
Rule1,Status2,1
Rule1,Status3,1
Rule1,Status4,2
Rule2,Status1,2
Rule2,Status2,1
Rule2,Status3,1
Rule2,Status4,3

I have unique rules (first column) stored in a list called Rules. I want my dictionary to look like the following:

DictionaryFull = {
                  'Rule1' : {1 : [Status1, Status2, Status3], 2 : [Status4]},
                  'Rule2' : {1 : [Status2, Status3], 2 : [Status1], 3 : [Status4]}
                 }

Here is what I tried:

openfile = ('data.csv', 'rU')
finalfile = csv.reader(openfile, delimiter=',')

FullDictionary = {}

for row in finalfile:
  for j in range (0, 300): #300 number of rules 
    if Rules[j] not in FullDictionary:
        for i in range(1, 71): #These are third column numbers 1 - 71 
            if i == int(row[2]) and row[0] == Rules[j]:
                FullDictionary = {Rules[j] : { i : [].append[row[1]}}
                    print FullDictionary

But I am getting the following as the result:

{'Rule1': {1 : None}} and so on

Am I doing something wrong? How to accomplish this task of having a dictionary with both another dictionary and a list.

I tried this:

def something():
    full_dictionary = {}
    with open(DataFilePath) as f:
        reader = csv.reader(f)
        for row in reader:
            rule = row[2], status = row[0], num = int(row[5])
            r = full_dictionary.setdefault(rule, {})
            r.setdefault(num, []).append(status)

    print full_dictionary

The error: ValueError: I/O operation on closed file

2 answers

0

list.appendвозвращает None, поэтому ваше задание Rules[j] = [].append([row[1])устанавливает Rules[j] = None.

Изменить что:

FullDictionary = {Rules[j] : { i : [row[1]}}

или же

old_value = Rules[j].get(i, [])
old_value.append(row[1])

в зависимости от того, что вы желая достичь.

2

HWO об использовании collection.defaultdict:

import csv
from collections import defaultdict

full_dictionary = defaultdict(lambda: defaultdict(list))
with open('data.csv') as f:
    reader = csv.reader(f)
    for rule, status, num in reader:
        full_dictionary[rule][num].append(status)

print full_dictionary

выход:

defaultdict(<function <lambda> at 0x00000000025A6438>, {
    'Rule2': defaultdict(<type 'list'>, {
        '1': ['Status2', 'Status3'],
        '3': ['Status4'],
        '2': ['Status1']
     }),
     'Rule1': defaultdict(<type 'list'>, {
         '1': ['Status1', 'Status2', 'Status3'],
         '2': ['Status4']
     })
})

Если вы не хотите использовать defaultdict, вы должны заботиться новый ключ.

Например, с помощью dict.setdefault:

import csv

full_dictionary = {}
with open('data.csv') as f:
    reader = csv.reader(f)
    for rule, status, num in reader:
        r = full_dictionary.setdefault(rule, {})
        r.setdefault(num, []).append(status)

print full_dictionary

выход:

{'Rule1': {'1': ['Status1', 'Status2', 'Status3'], '2': ['Status4']},
 'Rule2': {'1': ['Status2', 'Status3'], '2': ['Status1'], '3': ['Status4']}}