当前位置:嗨网首页>书籍在线阅读

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 循环的每次迭代中调用它不会有问题。