13-第2步_填充数据结构
第2步:填充数据结构
保存在 countyData
中的数据结构将是一个字典,以州的简称作为键。每个州的简称将映射到另一个字典,其中的键是该州的县的名称。每个县的名称又映射到一个字典,该字典只有两个键: 'tracts'
和 'pop'
。这些键映射到普查区数目和该县的人口。例如,该字典可能类似于:
{'AK': {'Aleutians East': {'pop': 3141, 'tracts': 1},
'Aleutians West': {'pop': 5561, 'tracts': 2},
'Anchorage': {'pop': 291826, 'tracts': 55},
'Bethel': {'pop': 17013, 'tracts': 3},
'Bristol Bay': {'pop': 997, 'tracts': 1},
--snip--
如果前面的字典保存在 countyData
中,下面的表达式求值结果如下:
>>> countyData['AK']['Anchorage']['pop']
291826
>>> countyData['AK']['Anchorage']['tracts']
55
一般来说, countyData
字典中的键看起来像这样:
countyData[state abbrev][county]['tracts']
countyData[state abbrev][county]['pop']
既然知道了 countyData
的结构,那就可以编写代码,并用县的数据填充它了。将下面的代码添加到程序的末尾:
#! python 3
# readCensusExcel.py - Tabulates population and number of census tracts for
# each county.
--snip--
for row in range(2, sheet.max_row + 1):
# Each row in the spreadsheet has data for one census tract.
state = sheet['B' + str(row)].value
county = sheet['C' + str(row)].value
pop = sheet['D' + str(row)].value
# Make sure the key for this state exists.
❶ countyData.setdefault(state, {})
# Make sure the key for this county in this state exists.
❷ countyData[state].setdefault(county, {'tracts': 0, 'pop': 0})
# Each row represents one census tract, so increment by one.
❸ countyData[state][county]['tracts'] += 1
# Increase the county pop by the pop in this census tract.
❹ countyData[state][county]['pop'] += int(pop)
# TODO: Open a new text file and write the contents of countyData to it.
最后的两行代码执行实际的计算工作,在 for
循环的每次迭代中,针对当前的县,增加 tracts
的值❸,并增加 pop
的值❹。
其他代码存在是因为只有 countyData
中存在键,你才能添加县字典作为州缩写键的值。(也就是说,如果 'AK'
键不存在, countyData['AK']['Anchorage']['tracts'] += 1
将导致一个错误。)为了确保州缩写的键存在,你需要调用 setdefault()
方法,在 state
还不存在时设置一个默认值❶。
正如 countyData
字典需要一个字典作为每个州缩写的值一样,这样的字典又需要一个字典作为每个县的键的值❷。这样的每个字典又需要键 'tracts'
和 'pop'
,它们的初始值为整数0(如果这个字典的结构令你混淆,回去看看本节开始处字典的例子)。
如果键已经存在,那么 setdefault()
不会做任何事情,因此在 for
循环的每次迭代中调用它不会有问题。