合并Pickle字典至嵌套字典遇KeyError:如何为不存在的键赋值?
解决嵌套字典填充的KeyError问题
你遇到的问题是因为直接访问多层嵌套字典的键时,上层键尚未创建,导致抛出KeyError。下面是几种实用的解决方法:
方法1:手动逐层检查并创建字典
最直观的方式,每一层都先判断键是否存在,不存在则创建空字典,再继续往下走:
import os import pickle PATH = '<SOME PATH>' all_dicts = os.listdir(PATH) one_dict = {} for filename in all_dicts: # 用with语句自动管理文件关闭,更安全 with open(os.path.join(PATH, filename), 'rb') as infile: new_dict = pickle.load(infile) splitted = filename.split('___') # 处理最后一个元素,去掉.pickle后缀 splitted[-1] = splitted[-1].split('.')[0] # 逐层检查并创建字典 dataset = splitted[0] num = splitted[1] norm = splitted[2] probs = splitted[3] metric = splitted[4] if dataset not in one_dict: one_dict[dataset] = {} if num not in one_dict[dataset]: one_dict[dataset][num] = {} if norm not in one_dict[dataset][num]: one_dict[dataset][num][norm] = {} if probs not in one_dict[dataset][num][norm]: one_dict[dataset][num][norm][probs] = {} one_dict[dataset][num][norm][probs][metric] = new_dict
方法2:使用嵌套的defaultdict
借助collections.defaultdict可以自动创建不存在的键对应的空字典,简化代码:
import os import pickle from collections import defaultdict PATH = '<SOME PATH>' all_dicts = os.listdir(PATH) # 定义四层嵌套的defaultdict,最后一层是普通字典 one_dict = defaultdict(lambda: defaultdict(lambda: defaultdict(lambda: defaultdict(dict)))) for filename in all_dicts: with open(os.path.join(PATH, filename), 'rb') as infile: new_dict = pickle.load(infile) splitted = filename.split('___') splitted[-1] = splitted[-1].split('.')[0] # 直接赋值,不存在的键会自动创建空字典 one_dict[splitted[0]][splitted[1]][splitted[2]][splitted[3]][splitted[4]] = new_dict # 如果需要把defaultdict转为普通字典(可选) one_dict = dict(one_dict)
方法3:动态遍历路径创建嵌套结构
如果嵌套层数不确定,或者想更通用,可以用循环遍历键路径,动态创建每一层:
import os import pickle PATH = '<SOME PATH>' all_dicts = os.listdir(PATH) one_dict = {} for filename in all_dicts: with open(os.path.join(PATH, filename), 'rb') as infile: new_dict = pickle.load(infile) splitted = filename.split('___') splitted[-1] = splitted[-1].split('.')[0] # 前四个元素是嵌套路径,最后一个是最终键 path_keys = splitted[:-1] final_key = splitted[-1] current_level = one_dict # 遍历路径,创建不存在的字典 for key in path_keys: if key not in current_level: current_level[key] = {} current_level = current_level[key] # 赋值最终的字典 current_level[final_key] = new_dict
这三种方法都能解决你的KeyError问题,其中方法2最简洁,方法3最通用,适合层数变化的场景。
内容的提问来源于stack exchange,提问作者Emil
相关产品推荐
相关产品推荐

