逐行读取与
关键词搜索
第二十天,我继续处理昨天保存的文本文件。文件中的每一行被读取成列表元素,清理换行符后,再交给不同函数显示、编号和搜索。
三个相似的读取方法
第一次练习时,我把 readlines() 写成了 readline()。程序没有报错,却只读取第一行,返回字符串,len() 因而统计出 16 个字符。修改后,三种方法的区别变得清楚:
read():读取全部内容,返回一个字符串readline():只读取一行,返回一个字符串readlines():读取全部行,返回一个列表
with open("learning_note.txt", "r", encoding="utf-8") as file: # 以读取模式打开学习记录文件
notes = file.readlines() # 读取所有行并组成列表
print("读取结果:", notes) # 输出列表并观察每个元素
print("数据类型:", type(notes)) # 验证结果类型是列表
print("记录数量:", len(notes)) # 统计文件中的记录行数
文件原来有三行,因此 notes 是包含三个字符串的列表,记录数量为 3。列表直接输出时,每个字符串末尾都能看到 \n。
strip() 产生新的干净字符串
strip() 会去掉字符串首尾的空白和换行符,但不会直接修改原来的字符串。练习中先建立 clean_notes,再把每条清理后的新字符串追加进去。
clean_notes = [] # 创建列表保存清理后的新字符串
number = 1 # 第一条记录的编号从 1 开始
for note in notes: # 逐条接收带换行符的原始记录
clean_note = note.strip() # 产生去掉换行符的新字符串
clean_notes.append(clean_note) # 把新字符串加入新列表
print(number, clean_note) # 输出编号和清理后的内容
number = number + 1 # 为下一条记录更新编号
print("原始列表:", notes) # 原列表仍然保留换行符
print("清理后的列表:", clean_notes) # 新列表不再包含换行符
这里最重要的不是“删除了 \n”,而是数据被分成了两份:notes 保留原始内容,clean_notes 保存处理后的内容。两个列表仍然都是三条记录。
把读取和整理封装成函数
load_notes() 负责读取与清理。如果文件不存在,FileNotFoundError 分支立即返回空列表;文件存在时,循环处理全部记录,最后返回干净列表。
def load_notes(): # 定义读取并整理记录的函数
clean_notes = [] # 准备保存清理后的记录
try: # 尝试打开并读取文件
with open("learning_note.txt", "r", encoding="utf-8") as file: # 自动管理文件
notes = file.readlines() # 得到原始记录列表
except FileNotFoundError: # 文件不存在时进入这里
return clean_notes # 返回空列表并结束函数
for note in notes: # 逐条处理原始记录
clean_note = note.strip() # 去掉换行符
clean_notes.append(clean_note) # 收集清理后的记录
return clean_notes # 把完整的新列表送出函数
显示函数处理正常和空列表
show_notes() 只负责显示。空列表会先输出提示,再通过 return 结束函数,所以后面的编号循环不会执行;非空列表则逐条编号输出。
def show_notes(notes): # 接收要显示的记录列表
if len(notes) == 0: # 判断列表是否为空
print("暂时没有学习记录") # 显示空列表提示
return # 立即结束函数
number = 1 # 设置第一条记录编号
for note in notes: # 遍历全部记录
print(number, note) # 输出编号和记录
number = number + 1 # 更新下一条编号
测试真实列表时正确输出三条记录;主动传入 [] 时,只显示“暂时没有学习记录”。没有返回值的 return 会让函数返回 None,并不是返回空列表。
用关键词筛选记录
搜索函数遍历全部记录,用 keyword in note 判断关键词是否出现在当前字符串中。符合条件的记录被收集进新列表,再交给显示函数。
def search_notes(notes, keyword): # 接收记录列表和搜索关键词
found_notes = [] # 保存符合条件的记录
for note in notes: # 遍历全部记录
if keyword in note: # 判断字符串是否包含关键词
found_notes.append(note) # 收集匹配记录
return found_notes # 返回搜索结果列表
keyword = input("请输入搜索关键词:") # 获取字符串关键词
search_result = search_notes(notes_result, keyword) # 调用函数并接住结果列表
show_notes(search_result) # 显示匹配记录或空列表提示
输入“文件”时找到三条记录,输入“列表”时没有匹配项,show_notes() 自动显示空列表提示。这说明同一个显示函数可以复用在全部记录和搜索结果上。
补全保存、读取与搜索流程
课程最后把第十九天的追加写入与今天的读取、显示、搜索连在一起。保存函数由工具协助补全并在测试副本中验证,真实记录文件没有因测试而改变。
def save_note(note): # 定义追加保存记录的函数
with open("learning_note.txt", "a", encoding="utf-8") as file: # 保留旧内容并追加
file.write(note + "\n") # 写入新记录并换行
new_note = input("请输入今天的学习记录:") # 获取一条新记录
save_note(new_note) # 先把记录保存进文件
notes_result = load_notes() # 保存后重新读取全部记录
show_notes(notes_result) # 显示更新后的记录列表
测试副本先有三条记录,输入“今天学习了逐行读取和关键词搜索”后变成四条,再搜索“搜索”得到一条匹配记录。执行顺序必须是先保存、再读取,否则变量中仍然只是保存前的旧列表。
今天真正掌握的内容
readlines()把文件的多行内容读取成列表strip()返回清理后的新字符串,不会自动修改原列表- 可以用新列表保存处理结果,同时保留原始数据
- 加载、显示和搜索可以拆成职责不同的函数
keyword in note能判断字符串是否包含关键词- 先保存再重新读取,才能得到包含新记录的最新列表
昨天,程序学会了把记录留下来;今天,这些记录不再只是一整段文字,而是变成能够逐条整理、显示和搜索的数据。