简体   繁体   中英

Trouble with adding key-value pairs a nested dictionary

I've been banging my head against the wall about this problem, and I feel like I'm really close! But not quite there yet. Any help is hugely appreciated. The format of the question will take some explaining but I don't think the coding itself will be very hard for you guys. I'm trying to write a function that takes the information inside a CSV file and creates a nested dictionary. Lines in the CSV file looks like this:

....  
2001,Spring,AFR 202 - 01,18,30,T|F,01:30 pm - 02:40 pm  
2002,Fall,AFR 208 - 01,29,30,M|Th,09:50 am - 11:00 am   
....

There are several hundred or so lines in the CSV. It's not necessary for you to pay close attention to any of the values in the CSV other than the year and the season (first two in each line), since I've taken care of stuff involving that.

The function should print out a nested dictionary with the calendar years as the keys on the top level. Each of these keys has a value as a dictionary, which in turn has as keys the two semesters Fall and Spring. To each season, I'm associating a list of dictionaries, one for every line in the dictionary.

So, it should look something like this (formatted for readability):

{
  "2001": {
    "Fall": [
      {
        "one": 40,
        "two": "AFR 207 - 01",
        "three": "W",
        "four": 44,
        "five": "Fall",
        "six": "07:00 pm - 09:30 pm",
        "seven": "2001"
      },
      ...
    ],
    "Spring": [
      {
        ...
      },
      ...
    ]
  },
  "2002" : {
    ...
  },
  ...
}

Explained another way, each year is a key in the biggest dictionary, and each key-value pair looks a bit like this:

year : { fall:[{ ...information...}],spring[{...information}] }

For each line in the CSV file, I have the {...information...} part down, and for each year I can pull out lines from the CSV and attach it to the appropriate year. I'm having trouble, though, getting both the 'fall' and the 'spring' lists to appear inside of the 'year' dictionary.

Note: entries in allClassInfo were made by formatting lines from the CSV file, and they look like this:

....
{'four': 15, 'one': 15, 'three': 'M|Th', 'six': '01:30 pm - 02:40 pm', 'two': 'WRIT 135 - 01', 'five': 'Fall', 'seven': '2014'},
{'four': 15, 'one': 15, 'three': 'M|Th', 'six': '02:50 pm - 04:00 pm', 'two': 'WRIT 140 - 01', 'five': 'Fall', 'seven': '2014'}
....

My code:

def byYear(filename):
    allClassInfo = classInfo(filename)
    bigDict={}
    for entry in allClassInfo:

        if ((entry.get('seven') in bigDict)  == False):
            if (entry.get('five') == 'Spring'):
                bigDict[entry.get('year')]= {'Spring':[entry]}

        if ((entry.get('seven') in bigDict)  == False):
            if (entry.get('five') == 'Fall'):
                bigDict[entry.get('year')]['Fall'] = [{'Fall':[entry]}]

    print bigDict

byYear('name.csv')

Which outputs things like:

'2008': {'Spring': [{'four': 50, 'one': 5, 'three': 'T|F', 'six': '09:50 am - 11:00 am', 'two': 'AFR 105 - 01', 'five': 'Spring', 'seven': '2008'}]}, 
'2009': {'Spring': [{'four': 25, 'one': 11, 'three': 'M|W|Th', 'six': '08:30 am - 09:40 am', 'two': 'AFR 102 - 01', 'five': 'Spring', 'seven': '2009'}]}

But no Fall info.

And I haven't gotten this far yet, but once each year is made, I'd include all of the other information by including some code like this:

    if ((entry.get('year') in bigDict)  == True):
        if (entry.get('semester') == 'Fall'):
            bigDict[entry.get('year')]['Fall'].append('entry')
        if (entry.get('semester') == 'Spring'):
            bigDict[entry.get('year')]['Spring'].append(entry)
if (entry.get('five') == 'Spring'):
    bigDict[entry.get('year')]= {'Spring':[entry]}

this line will over write the contents in bigDict[entry.get('year')] . To add key-value pair to dict , you can:

if (entry.get('five') == 'Spring'):
    bigDict[entry.get('year')]['Spring'] = [entry]

Python dictionaries have a setdefault function which will make this much easier. If the given key is already present in the dict, it will return the value for the key, otherwise it will create the key/value pair.

bigDict = {}
for entry in allClassInfo:
    year = entry.get('seven')
    season = entry.get('five')

    # first, make sure we have an entry for this year in bigDict
    yearDict = bigDict.setdefault(year, {})
    # then make an entry for this season
    list = yearDict.setdefault(season, [])
    # then, append to the list
    list.append(entry)

NOTE: This works because the inserted dict is returned by reference. For simple value types use get . Eg. this is how you'd count entries:

counts = {}
for entry in allClassInfo:
    year = entry.get('seven')
    counts[year] = counts.get(year, 0) + 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM