【问题标题】:Large nested dictionary of data only working with "last key"大型嵌套数据字典仅使用“最后一个键”
【发布时间】:2020-01-24 18:52:42
【问题描述】:

[编辑] - 不是字典本身的问题。原始文件“census2010.py”的未修改副本不会显示此问题。

我正在尝试将 Excel 数据编码到嵌套字典中以供进一步分析。

我希望能够从字典中读出任何键。例如,我希望以下工作:

>>> census2010.allData['AK']['Anchorage']
{'pop': 291826, 'tracts': 55}

我得到的是:

census2010.allData['AK']['Anchorage']
Traceback (most recent call last):
  File "<input>", line 1, in <module>
KeyError: 'AK'

唯一有效的键是:

census2010.allData['WY']['Weston']
{'pop': 3894, 'tracts': 1}

我已经使用 censuspopdata.xlsx 文件夹中的数据创建了 Census2010.py 文件(按照“自动化无聊的东西”第 12 章的过程)。

直接查看 Census2010.py 会显示所有嵌套键,但导入“census2010.py”并查询字典仅显示“最终”键。

这是生成 census2010.py 的脚本:(它运行没有错误)

import openpyxl, pprint, os
print('Opening workbook...')
os.getcwd()
p = os.getcwd()
os.chdir(p + '\\automatestuffdirectorytest\\')
wb = openpyxl.load_workbook('censuspopdata.xlsx')
sheet = wb['Population by Census Tract']
countyData = {}
print('Reading rows...')
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)
print('Writing results...')
resultFile = open('census2010.py', 'w')
resultFile.write('allData = ' + pprint.pformat(countyData))
resultFile.close()
print('Done.')

这是结果字典的一些片段(3143 行)

allData = {'AK': {'Aleutians East': {'pop': 3141, 'tracts': 1},
        'Aleutians West': {'pop': 5561, 'tracts': 2},
        'Anchorage': {'pop': 291826, 'tracts': 55}, # ...

--剪辑--

        'Yukon-Koyukuk': {'pop': 5588, 'tracts': 4}}, # ...

--剪辑--

 'WY': {'Albany': {'pop': 36299, 'tracts': 10}, # ...

--剪辑--

        'Weston': {'pop': 7208, 'tracts': 2}}}

但似乎唯一能找到的键是 [WY][Weston]

for i in allData.items():
...    print(i)
...    
('WY', {'Weston': {'pop': 3894, 'tracts': 1}})

调用键仅适用于 ['WY']['Weston']

census2010.allData['WY']['Weston']
{'pop': 3894, 'tracts': 1}

【问题讨论】:

  • 如何读取结果文件以将其转换成字典?
  • 请查看如何创建minimal reproducible example。现在很难说,因为我们没有(也不需要)您的原始数据,而且您的字典本身的格式可能与您预期的不同。如果您可以在遇到相同错误的情况下生成最小样本,那将是一个很好的起点。
  • 另外,考虑将生成的countyData 转储为json,而不是将其强制为str
  • 感谢您的回复。发布后,查看@r.ook 回复后,我尝试简单地复制文件并按预期导入副本!从字面上复制到“census2010copy.py”并导入使关键调用起作用。
  • 变量和函数名称应遵循lower_case_with_underscores 样式。除了其他人所说的 JSON,您确实应该使用上下文管理器来处理文件对象。

标签: python excel openpyxl dictionary-comprehension


【解决方案1】:

此代码可能会对您有所帮助: 注意:我没有使用 os 模块

# ! python3
# read_census_excel.txt - Tabultaes population and number of census tracts for
# each county.

import openpyxl, pprint

print('Opening workbook')
wb = openpyxl.load_workbook('censuspopdata.xlsx')
sheet = wb.get_sheet_by_name('Population by Census Tract')
county_data = {}

print('Reading rows...')
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.
    county_data.setdefault(state, {})
    # Make sure the key for this county in this state exists.
    county_data[state].setdefault(county, {'tracts': 0, 'pop': 0})

    # Each row represents one census tract, so increment by one.
    county_data[state][county]['tracts'] += 1
    # Increase the county pop by the pop in this census tract.
    county_data[state][county]['pop'] += int(pop)

# Open a new text file and write the contents of county_data to it.
print('Writing results...')
result_file = open('census2010.py', 'w')
result_file.write('all_data= ' + pprint.pformat(county_data))
result_file.close()
print('Done')

【讨论】:

    猜你喜欢
    • 2020-10-03
    • 1970-01-01
    • 2019-06-18
    • 1970-01-01
    • 2019-02-06
    • 2020-07-26
    • 2021-03-14
    • 1970-01-01
    相关资源
    最近更新 更多