【Python学习打卡-Day24】从不可变元组到漫游文件系统:掌握数据结构与OS模块

📋 前言

各位伙伴们,大家好!今天的学习内容非常特别,我们暂时从复杂的机器学习算法中抽身,回归到两个 Python 的基石上:元组 (Tuple)os 模块

你可能会问,这两者有什么关系?

  • 元组 ,代表了程序内部数据的稳定性与契约精神。为什么深度学习框架如此偏爱它?
  • os 模块 ,则是程序与外部世界(文件系统)沟通的桥梁与工具。如何让我们的代码不再局限于单个文件,而是能管理整个项目的数据?

今天,我们将通过一张"神图"彻底搞懂 Python 四大数据结构的使命,并学会使用 os 模块赋予我们的代码"探索"文件系统的能力。这对于我们未来处理大规模数据集、在服务器上工作至关重要。


一、再探数据结构:一张图搞懂 List, Tuple, Dict, Set 的天命

之前我们已经学习了多种数据结构,但可能还停留在"会用"的层面。今天,通过下面这张源自课程的总结图,我们将理解它们在机器学习/深度学习场景下的设计哲学和最佳实践

数据结构 核心特点 机器学习/深度学习中的应用
列表 (List) 可变 (Mutable)、有序、允许重复 收集训练过程中的指标 (losses.append(loss_value))、存储批次数据(转为 Tensor 前)、动态构建可变序列(如分词结果)。
元组 (Tuple) 不可变 (Immutable)、有序、允许重复、可哈希 定义张量/数组的形状 (Shape) (batch_size, 224, 224, 3)、定义固定的超参数(如卷积核大小)、作为字典的键来缓存结果 cache[('conv', 32)]
字典 (Dict) 可变 (Mutable)、键值对、键唯一且不可变 存储超参数 ({'lr': 0.001}), 存储评估结果 ({'acc': 0.85}), 构建模型配置 (JSON)、建立标签与索引的映射 {'cat': 0, 'dog': 1}
集合 (Set) 可变 (Mutable)、无序、元素唯一且不可变 获取数据集中唯一的类别标签、对特征名列表去重、快速检查成员是否存在(比列表快得多)、比较不同数据集的特征集异同。

Aha! Moment:为什么元组如此重要?

通过上表,我终于豁然开朗:元组的核心价值在于它的"不可变性"

在大型项目中,尤其是深度学习中,数据和参数的形状一旦确定,就不应该被意外修改。使用元组 (batch_size, height, width, channels) 来定义一个张量的形状,就像立下了一个"军令状",确保了后续所有操作的维度安全。

再回想昨天的 PipelinePipeline([ ('scaler', StandardScaler()), ('model', LogisticRegression()) ])

  • 外层的 列表 [] 提供了步骤的顺序和可修改性(我们可以增删步骤)。
  • 内层的 元组 () 则将步骤名和步骤对象牢牢"捆绑",这个对应关系是固定不变的。

这就是 Python 设计的精妙之处:用不同的数据结构来表达不同的"意图"。


二、程序的"眼睛"和"手":os 模块核心功能

如果说之前的代码都活在自己的小世界里,那么 os 模块就是它伸向外部真实文件系统的触手。这在处理图像数据集、管理模型文件、在无图形界面的服务器(如 Kaggle,

AutoDL)上工作时,是必备技能

2.1 定位:我在哪?周围有什么?

  • os.getcwd(): 获取当前工作目录 (Get Current Working Directory)。
  • os.listdir(path): 列出指定路径下的所有文件和文件夹名。
python 复制代码
import os

current_dir = os.getcwd()
print(f"我现在在这里: {current_dir}")

dir_content = os.listdir(current_dir)
print(f"我周围有这些东西: {dir_content}")

2.2 导航:如何安全地构建路径?

永远不要手动拼接路径字符串! 比如 path = dir + '/' + file。这在 Windows 系统下会失效,因为 Windows 的路径分隔符是 \

正确的做法是使用 os.path.join(),它会根据你的操作系统自动选择正确的分隔符。

python 复制代码
path_part1 = 'data'
path_part2 = 'images'
filename = 'cat.jpg'

# 跨平台的、安全的方式
full_path = os.path.join(path_part1, path_part2, filename)

print(full_path) 
# 在 Windows 上输出: 'data\\images\\cat.jpg'
# 在 Linux/macOS 上输出: 'data/images/cat.jpg'

2.3 探索:如何深度遍历整个文件夹?

这是 os 模块中最强大的功能之一:os.walk()。它就像一个勤劳的探险家,会深入你指定的目录,以及其中的每一个子目录,进行"深度优先"的遍历。

对于它访问的每一个目录,os.walk() 都会返回一个元组 (dirpath, dirnames, filenames)

  • dirpath: 当前目录的路径。
  • dirnames: 当前目录下的子文件夹名称列表。
  • filenames: 当前目录下的文件名称列表。

再次连接 :看,os.walk() 返回的核心信息就是一个元组,再次体现了元组用于承载一组固定结构数据的设计思想!


三、作业实践:打造一个命令行"目录树浏览器"

今天的作业是"对自己电脑的不同文件夹利用今天学到的知识操作下,理解下 os 路径"。让我们把这个作业做得更酷一点:编写一个函数,它可以像 Linux 的 tree 命令一样,可视化地打印出任何指定目录的结构。

这个练习将完美地结合 os.walk()os.path.join() 和字符串操作。

我的代码实现

python 复制代码
import os

def print_directory_tree(root_dir, indent_prefix=""):
    """
    以树状结构打印出指定目录的文件和文件夹。
    
    参数:
    - root_dir: 要遍历的根目录路径。
    - indent_prefix: 用于控制缩进的内部参数,调用时无需设置。
    """
    
    # --- 准备工作:获取目录内容并排序 ---
    try:
        # 获取所有条目并过滤掉隐藏文件 (如 .git, .vscode)
        items = [item for item in os.listdir(root_dir) if not item.startswith('.')]
        items.sort() # 排序以获得一致的输出
    except FileNotFoundError:
        print(f"错误: 目录 '{root_dir}' 不存在。")
        return
    except PermissionError:
        print(f"错误: 没有权限访问 '{root_dir}'。")
        return

    # --- 核心遍历逻辑 ---
    for i, item in enumerate(items):
        full_path = os.path.join(root_dir, item)
        is_last = (i == len(items) - 1) # 判断是否是当前层的最后一个条目

        # 打印当前条目的连接线和名称
        connector = "└── " if is_last else "├── "
        print(indent_prefix + connector + item)

        # 如果是文件夹,则递归调用本函数,并更新下一层的缩进前缀
        if os.path.isdir(full_path):
            new_prefix = "    " if is_last else "│   "
            print_directory_tree(full_path, indent_prefix + new_prefix)


# --- 作业执行 ---
# 1. 选择一个你想要探索的文件夹路径
#    可以是你的项目文件夹、下载文件夹等
#    为了安全,请避免选择系统根目录 C:\ 或 /
# target_directory = r"D:\MyProjects\Python-60-Days" # Windows 示例
target_directory = './'  # 使用当前目录作为示例

# 2. 开始打印目录树
print(f"🌳 目录树 for '{os.path.abspath(target_directory)}':")
print_directory_tree(target_directory)

运行结果(示例):

复制代码
🌳 目录树 for 'G:\study\pythonstudy\my_project':
├── data
│   ├── processed
│   └── raw
│       └── data1.csv
├── main.py
├── README.md
└── src
    ├── models
    │   └── model_a.py
    └── utils.py

通过这个练习,我对 os.walk 的"深度优先"遍历有了极深的体感。代码一层层深入,就像剥洋葱一样,直到最深处,再回溯到上一层,继续探索其他分支。


四、总结与心得

Day 24 的学习让我收获了两个维度的成长:

  1. 深入理解了"不变"的力量:我不再认为元组是"功能受限的列表"。我明白了它的"不可变性"是一种强大的设计特性,是构建稳定、可预测程序的基石。在定义模型配置、函数返回值时,我会优先考虑使用元组。

  2. 获得了与系统交互的能力os 模块为我的代码打开了一扇通往外部世界的大门。我不再是只能处理内存中数据的"书呆子",而是可以编写脚本来自动整理文件、批量处理数据、为大型项目构建清晰的目录结构。

  3. 培养了"服务器思维" :老师强调的 os.walk() 在无 GUI 环境下的重要性,让我提前有了在服务器上工作的意识。当面对只有命令行的 Linux 服务器时,这些工具就是我的眼睛和手,是必备的生存技能。

今天的学习,是编程内功的一次重要修炼。它让我们在攀登机器学习高峰的路上,步子迈得更稳、更扎实。

再次感谢 @浙大疏锦行 老师的精彩课程,将基础知识与高阶应用结合得如此完美!

相关推荐
FPGA小迷弟3 分钟前
高频时钟设计:FPGA 多时钟域同步与时序收敛实战方案
前端·学习·fpga开发·verilog·fpga
sensen_kiss19 分钟前
CPT306 Principles of Computer Games Design 电脑游戏设计原理 Pt.3 实时图形
学习·计算机视觉
SugarFreeOixi22 分钟前
MATLAB绘图风格记录NP类型
python·matlab·numpy
冥王丁B32 分钟前
第31章 Prompt 与聊天模型笔记
笔记·python·prompt
東雪木40 分钟前
编程算法学习——栈与队列算法
学习·算法·排序算法
左左右右左右摇晃41 分钟前
Java笔记——包装类(自动拆装箱)
java·笔记·python
青瓷程序设计1 小时前
【果蔬识别系统】Python+深度学习+人工智能+算法模型+图像识别+2026原创
人工智能·python·深度学习
ADHD多动联盟1 小时前
什么是儿童ADHD的运动干预方案?主要有怎样的应对分心走神的疗法?
学习·学习方法·玩游戏
Fairy要carry1 小时前
面试08-“生产者-消费者” 模型实现并发 Agent
python·面试
chushiyunen1 小时前
python和java的区别
python