Python嵌套字典操作:dict.copy()后迭代仍报字典大小变更错误
错误原因
dict.copy()是浅拷贝,只会生成新的外层字典对象,内部嵌套的所有字典还是和原字典共享同一内存地址。你代码中遍历的v(来自临时字典的内层字典)和执行pop操作的dict_of_dicts[k]是完全相同的对象,遍历对象的同时修改它的键数量,就会触发RuntimeError: dictionary changed size during iteration报错。
解决方案
有两种简单的修复方式可选:
方式1:遍历内层字典时生成固定快照
遍历内层字典的items()时先转为列表,相当于生成遍历瞬间的键值对快照,后续修改原字典不会影响遍历过程:
把内层循环的
for k2, v2 in v.items():
修改为
for k2, v2 in list(v.items()):
方式2:使用深拷贝生成完全独立的临时字典
导入Python内置的copy模块,用深拷贝生成完全独立的临时字典,遍历对象和修改对象完全隔离:
- 代码开头导入模块:
import copy - 把临时字典生成逻辑从
dict_of_dictsTemp = dict_of_dicts.copy()
修改为
dict_of_dictsTemp = copy.deepcopy(dict_of_dicts)
完整修正代码示例
import pandas as pd import copy def xls_to_dict_of_dict(filename): df = pd.read_excel(filename) df.fillna("NotaNumber", inplace=True) dict_of_dicts = {} try: for index, row in df.iterrows(): dict_of_dicts[row[1]] = {} for i in range(2, len(row)): dict_of_dicts[row[1]][row[i]] = df.iloc[index + 1][i] except: pass return dict_of_dicts if __name__ == '__main__': dict_of_dicts = xls_to_dict_of_dict('Excel.xlsx') # 方案1不需要改这里,用方案2的话替换为深拷贝即可 dict_of_dictsTemp = dict_of_dicts.copy() for k, v in dict_of_dictsTemp.items(): # 这里转成列表遍历避免修改时报错 for k2, v2 in list(v.items()): if v2 == "NotaNumber": dict_of_dicts[k].pop(k2) for k, v in dict_of_dicts.items(): for k2, v2 in v.items(): print(k2, v2)
内容的提问来源于stack exchange,提问作者Ahmed Seif
相关产品推荐
相关产品推荐

