如何创建嵌套字典并遍历列表添加元素(避免覆盖)
构建嵌套字典的解决方案
问题背景
需要遍历一组列表,将每个列表的元素按层级添加到空字典中,若对应层级已存在则跳过,避免覆盖原有内容。现有数据如下:
my_dictionary = {} file1 = ['model_a', 'part_a', 'category_a', 'format_a', 'version_a', 'filename_a'] file2 = ['model_b', 'part_a', 'category_a', 'format_a', 'version_a', 'filename_a'] file3 = ['model_a', 'part_b', 'category_a', 'format_a', 'version_a', 'filename_b'] file4 = ['model_c', 'part_a', 'category_a', 'format_a', 'version_a', 'filename_a'] file5 = ['model_b', 'part_a', 'category_a', 'format_b', 'version_a', 'filename_a'] file6 = ['model_a', 'part_a', 'category_a', 'format_a', 'version_b', 'filename_a'] file_list = [file1, file2, file3, file4, file5, file6]
已完成基础循环拆分元素:
for item in file_list: model, pn, category, file_format, version, filename = item
此前尝试直接写入会覆盖内容,用try/except检查层级时出现TypeError: 'set' object is not subscriptable错误,需要可行的实现方案。
解决方案
可以通过逐层检查字典层级的方式,确保每个层级不存在时才创建对应的结构,避免覆盖或类型错误。以下是几种实现方式:
方式一:逐层检查并创建
my_dictionary = {} for item in file_list: model, pn, category, file_format, version, filename = item # 检查并创建model层级 if model not in my_dictionary: my_dictionary[model] = {} # 检查并创建part层级 if pn not in my_dictionary[model]: my_dictionary[model][pn] = {} # 检查并创建category层级 if category not in my_dictionary[model][pn]: my_dictionary[model][pn][category] = {} # 检查并创建format层级 if file_format not in my_dictionary[model][pn][category]: my_dictionary[model][pn][category][file_format] = {} # 仅当version不存在时添加对应filename if version not in my_dictionary[model][pn][category][file_format]: my_dictionary[model][pn][category][file_format][version] = filename
这种方式逻辑直白,逐层验证每个层级的存在性,仅在缺失时创建新字典,最后处理version与filename的映射,完全避免覆盖问题。
方式二:用dict.setdefault()简化代码
setdefault()方法可在键不存在时设置默认值并返回,存在时直接返回现有值,能大幅简化层级检查的代码:
my_dictionary = {} for item in file_list: model, pn, category, file_format, version, filename = item # 逐层获取或创建对应层级的字典 model_dict = my_dictionary.setdefault(model, {}) pn_dict = model_dict.setdefault(pn, {}) category_dict = pn_dict.setdefault(category, {}) format_dict = category_dict.setdefault(file_format, {}) # 避免覆盖已有version的filename if version not in format_dict: format_dict[version] = filename
处理多文件名场景(可选)
如果同一个version对应多个filename,可以将filename存储为集合,自动去重同时避免类型错误:
my_dictionary = {} for item in file_list: model, pn, category, file_format, version, filename = item model_dict = my_dictionary.setdefault(model, {}) pn_dict = model_dict.setdefault(pn, {}) category_dict = pn_dict.setdefault(category, {}) format_dict = category_dict.setdefault(file_format, {}) # 用集合存储多个filename,自动去重 version_files = format_dict.setdefault(version, set()) version_files.add(filename)
这种方式不会触发'set' object is not subscriptable错误,因为我们是对集合调用add()方法,而非尝试下标访问集合。
验证结果
运行方式一的代码后,my_dictionary会生成如下嵌套结构:
{ 'model_a': { 'part_a': { 'category_a': { 'format_a': { 'version_a': 'filename_a', 'version_b': 'filename_a' } } }, 'part_b': { 'category_a': { 'format_a': { 'version_a': 'filename_b' } } } }, 'model_b': { 'part_a': { 'category_a': { 'format_a': { 'version_a': 'filename_a' }, 'format_b': { 'version_a': 'filename_a' } } } }, 'model_c': { 'part_a': { 'category_a': { 'format_a': { 'version_a': 'filename_a' } } } } }
内容的提问来源于stack exchange,提问作者boondockorphan
相关产品推荐
相关产品推荐

