第 5 课:Python 高级数据容器与文件操作 —— 数据去重、有序存储与持久化核心
前四课我们依次掌握了「基础数据类型」「流程控制」「函数封装」,能实现模块化的程序逻辑,但在实际开发中,还会遇到两个核心需求:
- 数据处理进阶:基础容器(列表、字典)无法高效解决「数据去重」「有序存储」等问题;
- 数据持久化:程序运行时的数据存储在内存中,程序关闭后数据丢失,需要将数据保存到文件中,实现长期存储。
本节课将学习 Python 高级数据容器(集合、有序字典)和 文件操作 两大核心内容:高级容器解决复杂数据处理需求,文件操作实现数据持久化,两者结合,让你的程序具备「高效数据处理」和「长期数据存储」的实战能力,是从入门到实战的关键跨越。
一、课程目标
✅ 掌握 集合(set) 的核心特性与操作,实现数据高效去重、交集 / 并集 / 差集计算;✅ 理解 有序字典(OrderedDict) 的应用场景,掌握有序键值对的存储与操作;✅ 吃透文件操作的核心流程:打开 - 读写 - 关闭,掌握open()函数与with语句的用法;✅ 熟练使用文件的 读操作(read()/readline()/readlines())和 写操作(write()/writelines());✅ 掌握文件的 追加模式 与 覆盖模式,理解不同打开模式的区别;✅ 能综合运用高级容器与文件操作,完成「数据去重统计并保存到文件」等实战任务;✅ 建立「数据持久化」思维,学会将程序数据保存到文件,实现跨运行周期的数据存储。
二、复习回顾:基础容器的局限与高级容器的诞生
我们已经掌握的基础数据容器(列表、字典、元组),在处理某些场景时存在明显局限:
- 列表:允许重复元素,去重需要手动遍历判断,效率低;
- 字典:Python3.7 + 才支持插入顺序,但无法直接实现「键的有序操作」(如按插入顺序删除);
- 所有基础容器:数据存储在内存中,程序关闭后数据丢失,无法持久化。
高级数据容器 正是为解决这些局限而生:
- 集合(set):天生去重,支持高效的集合运算(交集、并集、差集),适合处理无重复元素的场景;
- 有序字典(OrderedDict):严格保留键的插入顺序,支持按顺序操作键值对,适合需要有序存储的场景。
文件操作 则解决了数据持久化问题:将内存中的数据写入文件(硬盘存储),程序下次运行时可从文件中读取数据,实现数据的长期保存。
三、核心知识点 1:高级数据容器 —— 集合(set)—— 数据去重与集合运算的利器
3.1 集合的核心特性(必须掌握)
集合是 Python 中一种无序、可变、元素唯一的高级数据容器,用大括号{}包裹,元素之间用逗号分隔。核心特性总结为 3 点:
- 无序:元素无固定顺序,不支持索引和切片(这是与列表的核心区别);
- 元素唯一:集合中不会存在重复元素,天生支持去重(这是集合的核心优势);
- 可变:可以添加、删除元素,但元素必须是不可变类型(字符串、数字、元组,不能是列表、字典等可变类型)。
3.2 集合的定义与初始化
✅ 方式 1:直接用{}定义(注意:空集合不能用{},{}表示空字典)
python
运行
# 定义非空集合
s1 = {1, 2, 3, 3, 4} # 自动去重,重复元素3只保留一个
s2 = {"苹果", "香蕉", "苹果", "橘子"} # 字符串集合,自动去重
print(s1) # 输出:{1, 2, 3, 4}(无序,顺序可能不同)
print(s2) # 输出:{'苹果', '香蕉', '橘子'}(无序)
✅ 方式 2:用set()函数转换(最常用,适合将列表、字符串等转为集合去重)
python
运行
# 列表转集合:去重
lst = [1, 2, 2, 3, 3, 3]
s3 = set(lst)
print(f"列表转集合:{s3}") # 输出:{1, 2, 3}
# 字符串转集合:去重+无序
str1 = "Python"
s4 = set(str1)
print(f"字符串转集合:{s4}") # 输出:{'P', 'y', 't', 'h', 'o', 'n'}(顺序可能不同)
# 定义空集合:必须用set()
s5 = set()
print(f"空集合类型:{type(s5)}") # 输出:<class 'set'>
print(f"空字典类型:{type({})}") # 输出:<class 'dict'>
3.3 集合的常用操作(核心)
集合的操作主要分为两类:元素的增删改查 和 集合运算(交集、并集、差集)。
✅ 操作 1:元素的增删改查
(1)添加元素:add()(添加单个元素)、update()(添加多个元素)
python
运行
s = {1, 2, 3}
# add():添加单个元素,元素已存在则不报错
s.add(4)
s.add(3) # 元素3已存在,无操作
print(f"add后:{s}") # 输出:{1, 2, 3, 4}
# update():添加多个元素,接收可迭代对象(列表、元组、字符串等)
s.update([5, 6])
s.update("78")
print(f"update后:{s}") # 输出:{1, 2, 3, 4, 5, 6, '7', '8'}(无序)
(2)删除元素:remove()(元素不存在报错)、discard()(元素不存在不报错)、pop()(随机删除一个元素)
python
运行
s = {1, 2, 3, 4, 5}
# remove():删除指定元素,不存在则报错KeyError
s.remove(3)
# s.remove(10) # 报错:KeyError: 10
print(f"remove后:{s}") # 输出:{1, 2, 4, 5}
# discard():删除指定元素,不存在则不报错(推荐使用)
s.discard(4)
s.discard(10) # 无操作,不报错
print(f"discard后:{s}") # 输出:{1, 2, 5}
# pop():随机删除一个元素,返回被删除的元素(集合无序,无法指定)
deleted_num = s.pop()
print(f"pop删除的元素:{deleted_num}")
print(f"pop后:{s}") # 输出:{2, 5}(随机,结果可能不同)
(3)查询元素:in关键字(判断元素是否在集合中,效率极高)
python
运行
s = {1, 2, 3, 4, 5}
print(3 in s) # 输出:True
print(10 in s) # 输出:False
✅ 操作 2:集合运算(交集、并集、差集、对称差集)—— 集合的核心优势
集合运算用于处理两个集合之间的关系,是数学中集合概念的直接实现,效率远高于手动遍历列表实现。
python
运行
# 定义两个集合
s1 = {1, 2, 3, 4, 5}
s2 = {4, 5, 6, 7, 8}
# 1. 并集(|):两个集合中所有的元素(去重)
union_set = s1 | s2
print(f"并集:{union_set}") # 输出:{1, 2, 3, 4, 5, 6, 7, 8}
# 2. 交集(&):两个集合中共同的元素
intersection_set = s1 & s2
print(f"交集:{intersection_set}") # 输出:{4, 5}
# 3. 差集(-):s1中有但s2中没有的元素
difference_set = s1 - s2
print(f"差集(s1-s2):{difference_set}") # 输出:{1, 2, 3}
# 4. 对称差集(^):两个集合中互不相同的元素(并集 - 交集)
symmetric_diff_set = s1 ^ s2
print(f"对称差集:{symmetric_diff_set}") # 输出:{1, 2, 3, 6, 7, 8}
3.4 集合的应用场景(实战高频)
✅ 场景 1:列表去重(最常用)
python
运行
# 列表去重:将列表转为集合,再转回列表
lst = [1, 2, 2, 3, 3, 3, 4, 5, 5]
unique_lst = list(set(lst))
print(f"去重后的列表:{unique_lst}") # 输出:[1, 2, 3, 4, 5](顺序可能不同)
✅ 场景 2:判断两个列表的共同元素
python
运行
lst1 = [1, 2, 3, 4, 5]
lst2 = [4, 5, 6, 7, 8]
# 转集合后求交集
common_ele = list(set(lst1) & set(lst2))
print(f"两个列表的共同元素:{common_ele}") # 输出:[4, 5]
四、核心知识点 2:高级数据容器 —— 有序字典(OrderedDict)—— 有序键值对的存储
4.1 有序字典的核心特性
在 Python3.7 之前,普通字典(dict)是无序的,无法保留键的插入顺序;有序字典(OrderedDict) 是collections模块提供的高级容器,严格保留键的插入顺序,支持按插入顺序操作键值对。
Python3.7 及以上版本,普通字典已支持保留插入顺序,但OrderedDict仍有其独特优势:
- 支持按插入顺序删除键值对(
popitem(last=True/False)); - 支持重新排序(
move_to_end(key, last=True/False))。
4.2 有序字典的使用(需导入collections模块)
✅ 步骤 1:导入OrderedDict
python
运行
from collections import OrderedDict
✅ 步骤 2:定义与初始化
python
运行
# 定义有序字典
od = OrderedDict()
# 添加键值对(按插入顺序保存)
od["name"] = "张三"
od["age"] = 20
od["score"] = 95
print(od) # 输出:OrderedDict([('name', '张三'), ('age', 20), ('score', 95)])
✅ 步骤 3:常用操作(与普通字典类似,新增有序操作)
python
运行
from collections import OrderedDict
od = OrderedDict()
od["a"] = 1
od["b"] = 2
od["c"] = 3
# 1. 按插入顺序遍历(与普通字典3.7+相同)
for key, value in od.items():
print(f"{key}: {value}") # 输出:a:1 → b:2 → c:3
# 2. popitem():按插入顺序删除键值对,last=True(默认)删除最后一个,last=False删除第一个
last_item = od.popitem()
print(f"删除的最后一个元素:{last_item}") # 输出:('c', 3)
first_item = od.popitem(last=False)
print(f"删除的第一个元素:{first_item}") # 输出:('a', 1)
print(f"删除后:{od}") # 输出:OrderedDict([('b', 2)])
# 3. move_to_end():将指定键移动到开头或结尾
od["a"] = 1
od["c"] = 3
od.move_to_end("a", last=True) # 移动到结尾
print(f"a移动到结尾:{od}") # 输出:OrderedDict([('b', 2), ('c', 3), ('a', 1)])
od.move_to_end("c", last=False) # 移动到开头
print(f"c移动到开头:{od}") # 输出:OrderedDict([('c', 3), ('b', 2), ('a', 1)])
4.3 有序字典的应用场景
适合需要严格保留键的插入顺序且需要按顺序操作键值对的场景,如配置文件的有序解析、日志的有序记录等。
五、核心知识点 3:文件操作 —— 数据持久化的核心
5.1 文件操作的核心流程
文件操作的核心流程分为三步:打开文件 → 读写文件 → 关闭文件。
- 打开文件:使用
open()函数,建立程序与文件的连接,返回文件对象; - 读写文件:通过文件对象的读写方法,实现数据的读取或写入;
- 关闭文件:使用
close()方法,关闭程序与文件的连接,释放系统资源(必须执行,否则可能导致数据丢失或文件损坏)。
5.2 文件的打开与关闭(基础)
✅ 核心函数:open()
语法:open(file, mode='r', encoding=None)
file:文件路径(绝对路径或相对路径);mode:打开模式,默认'r'(只读),常用模式有'w'(写入)、'a'(追加)、'r+'(读写)等;encoding:文件编码,推荐使用'utf-8',避免中文乱码。
✅ 基础示例:打开并关闭文件
python
运行
# 打开文件(相对路径,文件需与程序在同一目录下)
f = open("test.txt", mode="r", encoding="utf-8")
# 执行读写操作(此处省略)
# 关闭文件(必须执行)
f.close()
✅ 进阶:使用with语句(推荐)
with语句会自动关闭文件,即使程序出现异常,也能保证文件被正确关闭,避免资源泄漏,是文件操作的推荐方式。
python
运行
# with语句自动关闭文件
with open("test.txt", mode="r", encoding="utf-8") as f:
# 执行读写操作
pass
# 离开with代码块,文件自动关闭
5.3 文件的打开模式(核心,必须掌握)
文件的打开模式决定了对文件的操作权限,常用模式如下:
| 模式 | 说明 | 注意事项 |
|---|---|---|
'r' |
只读模式(默认) | 文件必须存在,否则报错FileNotFoundError |
'w' |
写入模式 | 文件不存在则创建,文件存在则覆盖原有内容 |
'a' |
追加模式 | 文件不存在则创建,文件存在则在末尾追加内容 |
'r+' |
读写模式 | 文件必须存在,可同时读写 |
'w+' |
读写模式 | 文件不存在则创建,存在则覆盖 |
'a+' |
读写模式 | 文件不存在则创建,存在则追加 |
5.4 文件的读操作(读取文件内容到程序)
文件对象提供了三种常用的读方法:read()、readline()、readlines()。
✅ 方法 1:read(size=-1)—— 读取全部内容或指定字节数
python
运行
# 读取全部内容
with open("test.txt", mode="r", encoding="utf-8") as f:
content = f.read()
print("文件全部内容:")
print(content)
# 读取指定字节数(英文1个字符=1字节,中文1个字符=3字节(utf-8编码))
with open("test.txt", mode="r", encoding="utf-8") as f:
content = f.read(5) # 读取前5个字符
print(f"\n前5个字符:{content}")
✅ 方法 2:readline()—— 逐行读取内容
适合读取大文件,避免一次性加载全部内容到内存。
python
运行
# 逐行读取
with open("test.txt", mode="r", encoding="utf-8") as f:
line1 = f.readline() # 读取第一行
line2 = f.readline() # 读取第二行
print(f"第一行:{line1.strip()}") # strip()去除换行符
print(f"第二行:{line2.strip()}")
✅ 方法 3:readlines()—— 读取所有行,返回列表
python
运行
# 读取所有行,返回列表
with open("test.txt", mode="r", encoding="utf-8") as f:
lines = f.readlines()
print("所有行:")
for i, line in enumerate(lines): # enumerate()获取行号
print(f"第{i+1}行:{line.strip()}")
5.5 文件的写操作(将程序数据写入文件)
文件对象提供了两种常用的写方法:write()、writelines()。
✅ 方法 1:write(content)—— 写入字符串内容
python
运行
# 写入模式('w'):覆盖原有内容
with open("test.txt", mode="w", encoding="utf-8") as f:
f.write("Hello Python!\n") # \n表示换行
f.write("这是文件的写入操作。\n")
# 追加模式('a'):在末尾追加内容
with open("test.txt", mode="a", encoding="utf-8") as f:
f.write("这是追加的内容。\n")
✅ 方法 2:writelines(iterable)—— 写入可迭代对象(列表、元组等)
python
运行
# 写入列表内容
lines = ["第一行内容\n", "第二行内容\n", "第三行内容\n"]
with open("test.txt", mode="w", encoding="utf-8") as f:
f.writelines(lines)
5.6 实战:文件的复制操作
python
运行
# 复制文件:读取源文件内容,写入目标文件
def copy_file(source_file, target_file):
"""复制文件"""
with open(source_file, mode="r", encoding="utf-8") as f_src:
content = f_src.read()
with open(target_file, mode="w", encoding="utf-8") as f_tgt:
f_tgt.write(content)
print(f"文件复制完成:{source_file} → {target_file}")
# 调用函数
copy_file("source.txt", "target.txt")
六、综合实操案例(整合高级容器与文件操作)
案例 1:学生成绩去重统计并保存到文件
✅ 需求:接收用户输入的多个学生成绩,去重后统计最高分、最低分、平均分,将统计结果保存到文件中。✅ 知识点:集合去重、列表操作、文件写操作、函数封装。
python
运行
def stat_scores():
"""统计学生成绩,去重后保存结果到文件"""
# 1. 接收用户输入
scores_input = input("请输入学生成绩,用逗号分隔:")
# 2. 转换为列表并去重
scores_lst = list(map(int, scores_input.split(","))) # 字符串转整数列表
unique_scores = list(set(scores_lst)) # 去重
if not unique_scores:
print("未输入有效成绩!")
return
# 3. 统计数据
max_score = max(unique_scores)
min_score = min(unique_scores)
avg_score = round(sum(unique_scores) / len(unique_scores), 1)
# 4. 准备保存内容
result = f"=== 学生成绩统计结果 ===\n"
result += f"原始成绩:{scores_lst}\n"
result += f"去重后成绩:{unique_scores}\n"
result += f"最高分:{max_score}\n"
result += f"最低分:{min_score}\n"
result += f"平均分:{avg_score}\n"
# 5. 写入文件
with open("score_stat.txt", mode="w", encoding="utf-8") as f:
f.write(result)
print("统计结果已保存到 score_stat.txt 文件中!")
# 调用函数
stat_scores()
案例 2:待办事项管理系统(支持持久化)
✅ 需求:实现一个简单的待办事项管理系统,支持添加、查询、删除待办事项,并将待办事项保存到文件中,程序重启后可读取之前的待办事项。✅ 知识点:有序字典、文件读写、流程控制、函数封装。
python
运行
from collections import OrderedDict
import os
def load_todos():
"""从文件加载待办事项"""
todos = OrderedDict()
if os.path.exists("todos.txt"): # 判断文件是否存在
with open("todos.txt", mode="r", encoding="utf-8") as f:
lines = f.readlines()
for line in lines:
line = line.strip()
if line:
index, content = line.split("|", 1)
todos[index] = content
return todos
def save_todos(todos):
"""将待办事项保存到文件"""
with open("todos.txt", mode="w", encoding="utf-8") as f:
for index, content in todos.items():
f.write(f"{index}|{content}\n")
def add_todo(todos):
"""添加待办事项"""
content = input("请输入待办事项内容:")
index = str(len(todos) + 1)
todos[index] = content
save_todos(todos)
print(f"待办事项添加成功!序号:{index}")
def query_todos(todos):
"""查询所有待办事项"""
if not todos:
print("暂无待办事项!")
return
print("=== 待办事项列表 ===")
for index, content in todos.items():
print(f"{index}. {content}")
def delete_todo(todos):
"""删除待办事项"""
if not todos:
print("暂无待办事项可删除!")
return
index = input("请输入要删除的待办事项序号:")
if index in todos:
del todos[index]
# 重新排序序号
new_todos = OrderedDict()
for i, (_, content) in enumerate(todos.items(), 1):
new_todos[str(i)] = content
save_todos(new_todos)
print("待办事项删除成功!")
return new_todos
else:
print("输入的序号不存在!")
return todos
def todo_system():
"""待办事项管理系统主函数"""
todos = load_todos()
while True:
print("\n=== 待办事项管理系统 ===")
print("1. 添加待办事项")
print("2. 查询待办事项")
print("3. 删除待办事项")
print("4. 退出系统")
choice = input("请输入操作序号:")
if choice == "1":
add_todo(todos)
elif choice == "2":
query_todos(todos)
elif choice == "3":
todos = delete_todo(todos)
elif choice == "4":
print("感谢使用待办事项管理系统!")
break
else:
print("输入无效,请重新选择!")
# 启动系统
todo_system()
七、课后作业(基础 + 进阶,巩固必做)
✅ 基础作业(掌握核心用法)
- 定义函数
remove_duplicates(lst):接收一个列表,返回去重后的新列表(使用集合实现,保持元素顺序可使用OrderedDict); - 编写程序:读取一个文本文件,统计文件中出现的所有单词,并去重,将去重后的单词保存到新文件中;
- 实现文件的追加操作:向一个已存在的文件中,追加 3 行新内容。
✅ 进阶作业(综合运用)
- 基于集合的集合运算,编写程序:接收两个用户输入的列表,输出它们的并集、交集、差集,并将结果保存到文件中;
- 完善待办事项管理系统,新增功能:修改待办事项内容;
- 思考:文件操作中,
'w'模式和'a'模式的核心区别是什么?使用'w'模式时需要注意什么?
八、后续学习指引
本节课我们掌握了Python 高级数据容器(集合、有序字典)和文件操作的核心知识,实现了数据的高效去重、有序存储和持久化,让程序具备了实战所需的核心数据处理能力。👉 下一课我们将学习 Python 异常处理与模块导入 —— 掌握异常处理机制(try-except),解决程序运行时的错误;学会导入和使用模块(内置模块、第三方模块、自定义模块),实现代码的复用与扩展,让程序更健壮、更具扩展性。
九、本节课核心总结
- 集合(set):无序、元素唯一、可变,核心优势是去重和集合运算(交集、并集、差集),适合处理无重复元素的场景;
- 有序字典(OrderedDict):严格保留键的插入顺序,支持按顺序操作键值对,适合需要有序存储的场景;
- 文件操作核心流程:打开(
open())→ 读写(read()/write()等)→ 关闭(close()),推荐使用with语句自动关闭文件; - 文件打开模式:
'r'(只读)、'w'(写入,覆盖)、'a'(追加)是最常用的三种模式,需根据需求选择; - 数据持久化:通过文件操作将内存中的数据写入硬盘文件,实现程序关闭后数据不丢失,是实战程序的必备功能;
- 核心思维:根据数据处理需求选择合适的容器(去重用集合、有序键值对用 OrderedDict),通过文件操作实现数据的长期存储。
所有评论(0)