Python · Day 20

逐行读取与
关键词搜索

第二十天,我继续处理昨天保存的文本文件。文件中的每一行被读取成列表元素,清理换行符后,再交给不同函数显示、编号和搜索。

三个相似的读取方法

第一次练习时,我把 readlines() 写成了 readline()。程序没有报错,却只读取第一行,返回字符串,len() 因而统计出 16 个字符。修改后,三种方法的区别变得清楚:

  • read():读取全部内容,返回一个字符串
  • readline():只读取一行,返回一个字符串
  • readlines():读取全部行,返回一个列表
day20.py
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,再把每条清理后的新字符串追加进去。

day20.py
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 分支立即返回空列表;文件存在时,循环处理全部记录,最后返回干净列表。

note_reader.py
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 结束函数,所以后面的编号循环不会执行;非空列表则逐条编号输出。

note_reader.py
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 判断关键词是否出现在当前字符串中。符合条件的记录被收集进新列表,再交给显示函数。

note_reader.py
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() 自动显示空列表提示。这说明同一个显示函数可以复用在全部记录和搜索结果上。

补全保存、读取与搜索流程

课程最后把第十九天的追加写入与今天的读取、显示、搜索连在一起。保存函数由工具协助补全并在测试副本中验证,真实记录文件没有因测试而改变。

note_reader.py
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 能判断字符串是否包含关键词
  • 先保存再重新读取,才能得到包含新记录的最新列表

昨天,程序学会了把记录留下来;今天,这些记录不再只是一整段文字,而是变成能够逐条整理、显示和搜索的数据。