Python 在嵌套字典中添加键值对时出现问题

Python 在嵌套字典中添加键值对时出现问题,python,csv,dictionary,Python,Csv,Dictionary,我一直在为这个问题大发雷霆,我觉得我真的很接近了!但还不完全是这样。 非常感谢您的帮助。问题的形式需要一些解释,但我认为编码本身对你们来说并不难。 我正在尝试编写一个函数,它将CSV文件中的信息提取出来,并创建一个嵌套字典。 CSV文件中的行如下所示: .... 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 ..

我一直在为这个问题大发雷霆,我觉得我真的很接近了!但还不完全是这样。 非常感谢您的帮助。问题的形式需要一些解释,但我认为编码本身对你们来说并不难。 我正在尝试编写一个函数,它将CSV文件中的信息提取出来,并创建一个嵌套字典。 CSV文件中的行如下所示:

....  
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   
....
CSV中大约有几百行。你没有必要密切注意任何问题 CSV中除年份和季节以外的其他值(每行的前两个),因为我已经注意到 关于那件事

该函数应该打印出一个嵌套字典,其中日历年作为顶层的键。 每一个键都有一个值作为字典,而字典又有两个学期秋和春的键。 每一季,我都会关联一个字典列表,字典中每一行对应一个

因此,它应该是这样的(为可读性而格式化):

另一种解释是,每年都是最大字典中的一个键,每个键值对看起来有点像这样:

year : { fall:[{ ...information...}],spring[{...information}] }
....
{'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'}
....
    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)
对于CSV文件中的每一行,我都有{…信息…}部分,对于每一年,我都可以从CSV中提取行并将其附加到相应的年份。不过,我遇到了麻烦,因为我无法将“秋季”和“春季”列表同时出现在“年度”词典中

注意:allClassInfo中的条目是通过格式化CSV文件中的行来创建的,它们如下所示:

year : { fall:[{ ...information...}],spring[{...information}] }
....
{'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'}
....
    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)
我的代码:

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')
输出如下内容:

'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'}]}
但没有秋季信息

我还没有做到这一点,但每年完成后,我都会通过包含以下代码来包含所有其他信息:

year : { fall:[{ ...information...}],spring[{...information}] }
....
{'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'}
....
    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)
此行将覆盖
bigDict[entry.get('year')]
中的内容。 要将键值对添加到
dict
,您可以:

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

Python字典有一个
setdefault
函数,这将使它变得更容易。如果给定的密钥已经存在于dict中,它将返回该密钥的值,否则将创建密钥/值对

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)
注意:这是因为插入的dict是通过引用返回的。对于简单的值类型,请使用
get
。这是你计算参赛人数的方法:

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

你会包括一个文件的链接(它的一小部分),你从中读取这些数据。回答你的问题会更有帮助,下面是文件:谢谢!我现在看到它是如何被覆盖的。然而,当我输入您建议的代码时,在打印了一段时间后,我的文本编辑器给了我“KeyError:”2001“,您知道为什么会发生这种情况吗?“Spring”键是在我们编写bigDict[entry.get('year')][Spring']时创建的,还是在我们编写bigDict[entry.get('year')][Spring']时添加的?太酷了!非常感谢。我有点困惑如何使用它来输入所有其他的{…信息…},虽然,因为当我使用它时,我/做/得到了完整的框架,包括年份和季节等等,但是只有一行的信息在每年的春秋字典中。啊,我在你的问题中遗漏了这一点。要将列表添加到
yearDict
,可以再次使用相同的功能。