0

0

从文件名列表创建嵌套字典的实用指南

聖光之護

聖光之護

发布时间:2025-10-28 14:48:01

|

920人浏览过

|

来源于php中文网

原创

从文件名列表创建嵌套字典的实用指南

本文档旨在指导开发者如何根据包含结构信息的文件名列表,高效地构建嵌套字典。我们将探讨一种通用的方法,该方法可以处理不同深度的嵌套,并提供代码示例,帮助你理解并实现这一过程。通过预定义字典结构并动态填充,我们可以避免深度嵌套问题,最终得到易于访问和管理的数据结构。

理解问题

假设你有一个文件夹,其中包含多个文件。这些文件的文件名编码了你想要创建的嵌套字典的结构。例如,文件名 vz_ERA_Neural_Water_Forecast.npy 表示一个名为 vz 的主字典,其中包含键 ERA,ERA 下包含键 Neural,以此类推。文件的内容将成为最终字典结构中对应的值。

挑战在于如何自动加载这些文件,解析文件名以提取键,并将文件内容正确地放置到嵌套字典的相应位置,同时处理不同深度的嵌套。

解决方案概述

解决这个问题的关键在于:

  1. 提取文件名中的键: 从每个文件名中提取出表示字典层级结构的键。
  2. 预定义字典结构: 根据已知的字典结构,预先创建嵌套字典的框架。
  3. 动态填充字典: 遍历文件,解析文件名,并将文件内容填充到预定义的字典结构中。

详细步骤

1. 提取文件名中的键

首先,我们需要从文件名中提取键。以下代码展示了如何实现:

Adrenaline
Adrenaline

软件调试助手,识别和修复代码中错误

下载
import os
from pathlib import Path

def extract_keys_from_filename(filename, root_key='vz'):
    """从文件名中提取键,移除文件扩展名和根键."""
    file_no_ext = Path(filename).stem  # 移除文件扩展名
    keys = file_no_ext.split('_')
    if root_key in keys:
        keys.remove(root_key)
    return keys

# 示例
filename = 'vz_ERA_Neural_Water_Forecast.npy'
keys = extract_keys_from_filename(filename)
print(keys)  # 输出: ['ERA', 'Neural', 'Water', 'Forecast']

2. 预定义字典结构

预定义字典结构可以避免深度嵌套问题,并提高代码的可读性和可维护性。 如果事先知道字典的结构,可以手动创建一个初始字典,或者根据需要动态构建。

def create_empty_nested_dict(structure):
    """根据给定的结构创建空的嵌套字典."""
    result = {}
    for key1, sub_dict1 in structure.items():
        result[key1] = {}
        for key2, sub_dict2 in sub_dict1.items():
            result[key1][key2] = {}
            for key3 in sub_dict2:
                result[key1][key2][key3] = None  # 或者任何默认值
    return result

# 示例结构
structure = {
    'Q': {
        'Polynomial': ['Reof', 'Training_Data'],
        'Neural': ['Reof', 'Training_Data']
    },
    'ERA': {
        'Polynomial': ['Reof', 'Training_Data'],
        'Neural': ['Reof', 'Training_Data']
    }
}

# 创建空的嵌套字典
vz_reloaded = create_empty_nested_dict(structure)
print(vz_reloaded)

3. 动态填充字典

现在,我们可以遍历文件,提取键,读取文件内容,并将内容填充到预定义的字典结构中。

import os
from pathlib import Path
import numpy as np
import xarray as xr

def populate_dictionary(directory, vz_reloaded, fileNamesAndTypes_check, root_key='vz'):
    """遍历目录,读取文件,并填充字典."""
    files = os.listdir(directory)
    # 移除不需要的文件
    if 'fileNamesAndTypes.txt' in files:
        files.remove('fileNamesAndTypes.txt')
    files = [f for f in files if not f.startswith('.')]

    for file in files:
        keys = extract_keys_from_filename(file, root_key)
        file_path = Path(directory, file)
        fileNoExt = Path(file).stem
        reloadedType = fileNamesAndTypes_check[fileNoExt]

        try:
            if reloadedType == str:
                with open(file_path, 'rb') as f:
                    contents = f.read()
            elif reloadedType == xr.core.dataset.Dataset:
                contents = xr.open_dataset(file_path)
            elif reloadedType == xr.core.dataarray.DataArray:
                contents = xr.open_dataarray(file_path)
            elif reloadedType == int:
                contents = np.load(file_path).item()
            elif reloadedType == list:
                contents = np.load(file_path).tolist()
            elif reloadedType == np.ndarray:
                contents = np.load(file_path)
            else:
                contents = None  # Handle other types as needed

            # 根据键的长度动态赋值
            if len(keys) == 3:
                vz_reloaded[keys[0]][keys[1]][keys[2]] = contents
            elif len(keys) == 4:
                vz_reloaded[keys[0]][keys[1]][keys[2]][keys[3]] = contents
            elif len(keys) == 5:
                vz_reloaded[keys[0]][keys[1]][keys[2]][keys[3]][keys[4]] = contents
            # 可以根据需要添加更多的嵌套层级
        except Exception as e:
            print(f"Error processing file {file}: {e}")
            print(f"Problematic keys: {keys}")

    return vz_reloaded

# 示例用法
# 假设 fc.selected 是你的根目录
#directory = Path(fc.selected, 'vz_save')
# 使用示例数据,替换为你的真实目录
directory = 'vz_save'

# 假设 fileNamesAndTypes_check 已经定义
#fileNamesAndTypes_check = ...
fileNamesAndTypes_check = {
    'ERA_Neural_Reof': str,
    'ERA_Neural_Training_Data': np.ndarray,
    'Q_Polynomial_Reof': str,
    'Q_Polynomial_Training_Data': np.ndarray,
}

# 确保目录存在
os.makedirs(directory, exist_ok=True)

# 创建示例文件
with open(Path(directory, 'ERA_Neural_Reof.txt'), 'w') as f:
    f.write("ERA Neural Reof Content")
np.save(Path(directory, 'ERA_Neural_Training_Data.npy'), np.array([1, 2, 3]))
with open(Path(directory, 'Q_Polynomial_Reof.txt'), 'w') as f:
    f.write("Q Polynomial Reof Content")
np.save(Path(directory, 'Q_Polynomial_Training_Data.npy'), np.array([4, 5, 6]))

vz_reloaded = create_empty_nested_dict(structure)
vz_reloaded = populate_dictionary(directory, vz_reloaded, fileNamesAndTypes_check)

print(vz_reloaded)

代码解释:

  • populate_dictionary 函数接受目录路径、预定义的字典结构和 fileNamesAndTypes_check 作为输入。
  • 它遍历目录中的每个文件,提取键,并根据 fileNamesAndTypes_check 中定义的类型读取文件内容。
  • 使用 try...except 块来处理可能发生的任何错误,例如文件不存在或类型不匹配。
  • 根据键的长度,将文件内容放置到字典的相应位置。

注意事项

  • 错误处理: 在实际应用中,需要添加更完善的错误处理机制,例如处理文件不存在、类型不匹配等情况。
  • 文件类型处理: 上面的代码只处理了 str, xr.core.dataset.Dataset, xr.core.dataarray.DataArray, int, list, 和 np.ndarray 类型的文件。你需要根据实际情况添加对其他文件类型的支持。
  • 字典结构: 确保预定义的字典结构与文件名中编码的结构一致。
  • 文件命名规范: 确保文件名遵循一致的命名规范,以便正确提取键。
  • 内存管理: 如果处理大量文件,请注意内存管理,避免一次性加载所有文件到内存中。可以使用迭代器或生成器来逐个处理文件。
  • 类型检查: fileNamesAndTypes_check 字典至关重要,确保它准确地映射文件名(无扩展名)到预期的数据类型。如果类型不匹配,会导致数据加载错误。

总结

通过预定义字典结构,并根据文件名动态填充内容,我们可以有效地从文件系统重建嵌套字典。这种方法避免了深度嵌套问题,提高了代码的可读性和可维护性。在实际应用中,请务必注意错误处理、文件类型处理和内存管理,以确保代码的健壮性和性能。

相关专题

更多
数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

307

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

222

2025.10.31

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

381

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

542

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

53

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

197

2025.08.29

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

536

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

17

2025.12.22

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

25

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 16.7万人学习

Rust 教程
Rust 教程

共28课时 | 4.8万人学习

Git 教程
Git 教程

共21课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号