欢迎来到 “5天学会Python” 实战营!
本系列专为已有一定编程基础(例如熟悉 Java, C++, JavaScript 等)的你设计。我们不会从“什么是变量”或“什么是循环”开始,而是通过每天一个有趣的项目,带你领略 Python 语法的简洁之美、标准库的强大,并快速建立起“Pythonic”的编程思维。
准备好了吗?让我们开始第一天的挑战!
今日目标:构建一个命令行词频分析器
忘掉 “Hello, World!” 吧。今天,我们要编写一个非常实用的小工具:一个可以分析任何英文文本文件,并统计出词频最高的单词的命令行程序。
这个项目将带你熟悉:
- Python 的文件读写:如何优雅地处理文件。
- 核心数据结构:
列表 (list)和字典 (dict)的妙用。 - 字符串处理:Python 处理文本的强大能力。
- 列表推导式 (List Comprehension):写出更简洁、更 Pythonic 的代码。
- 标准库
collections:发现 Python 自带的“瑞士军刀”。 - 命令行参数:让你的脚本更具通用性。
最终效果:
我们希望在命令行中这样运行我们的脚本:
python word_counter.py article.txt 10
程序会读取 article.txt 文件,并输出其中出现频率最高的 10 个单词及其次数。
Step 1: 环境准备
- 安装 Python 3: 确保你的电脑已经安装了 Python 3。打开终端或命令行,输入
python3 --version或python --version检查。 - 选择代码编辑器: VS Code, PyCharm, Sublime Text 都是不错的选择。
- 创建项目: 新建一个文件夹,例如
python-day1,并在其中创建一个word_counter.py文件和一个示例文本文件article.txt。
在 article.txt 中,粘贴任意一段英文,例如:
Python is a high-level, interpreted, general-purpose programming language. Its design philosophy emphasizes code readability with its notable use of significant indentation. Python is dynamically-typed and garbage-collected.
Step 2: 读取文件内容
在其他语言中,你可能需要手动打开文件,然后在一个 finally 块中确保关闭它。Python 提供了一个更优雅的 with 语句,可以自动管理文件的打开和关闭。
在 word_counter.py 中写入:
import sys
def read_file(file_path):
"""读取文件内容并返回文本字符串"""
try:
# 'with' 语句能确保文件在操作完成后被正确关闭,即使发生错误。
# 'r' 表示读取模式, 'utf-8' 是推荐的文本编码。
with open(file_path, 'r', encoding='utf-8') as file:
return file.read()
except FileNotFoundError:
print(f"错误: 文件 '{file_path}' 未找到。")
# 退出程序,状态码 1 表示有错误发生。
sys.exit(1)
# --- 主程序入口 ---
if __name__ == '__main__':
text_content = read_file('article.txt')
print(text_content)
知识点:
with open(...) as ...: 这是处理文件 I/O 的首选方式,它被称为“上下文管理器”,能保证资源的正确释放。try...except: Python 的异常处理机制。我们捕捉FileNotFoundError异常,提供友好的错误提示。sys.exit(1): 终止程序。在脚本中,非零的退出码通常表示发生了错误。if __name__ == '__main__':: 这是一个非常重要的 Python 惯例。只有当这个脚本被直接执行时,这部分代码才会运行。如果它被其他脚本作为模块导入,则不会运行。
现在运行 python word_counter.py,你应该能看到 article.txt 的内容被打印出来。
Step 3: 文本处理与词频统计
拿到文本后,我们需要:
- 将所有单词转为小写,以避免 “Python” 和 “python” 被当成两个词。
- 将文本分割成单词列表。
- 去除单词旁边的标点符号。
- 统计每个单词出现的次数。
字典 (dict) 是存储键值对的完美工具,非常适合用于词频统计。
让我们来扩展代码:
import sys
import re
def count_words(text):
"""统计文本中每个单词的频率"""
# 1. 全部转为小写
text = text.lower()
# 2. 使用正则表达式替换所有非字母数字的字符为空格
# [^a-z0-9\s] 匹配任何不是小写字母、数字或空白字符的字符
text = re.sub(r'[^a-z0-9\s]', ' ', text)
# 3. 按空白字符分割成单词列表
words = text.split()
# 4. 统计词频
word_counts = {}
for word in words:
# dict.get(key, default) 是一个安全获取值的方法
# 如果 word 已在字典中,返回其值并+1;否则返回默认值0,再+1。
word_counts[word] = word_counts.get(word, 0) + 1
return word_counts
# --- 主程序入口 ---
if __name__ == '__main__':
text_content = read_file('article.txt')
word_freq = count_words(text_content)
print(word_freq)
知识点:
text.lower(): 字符串的内置方法,返回一个新的小写字符串。re.sub():re是 Python 的正则表达式模块。re.sub(pattern, repl, string)用于在string中查找pattern并替换为repl。这里我们用它来清除标点。text.split(): 将字符串按空白(空格、换行、制表符)分割,返回一个单词列表。字典 (dict): 类似于 Java 的HashMap或 JS 的Object。word_counts.get(word, 0): 这是一个非常 Pythonic 的用法。相比于先检查word是否在word_counts中,.get()方法可以提供一个默认值(这里是0),让代码更简洁、高效。
再次运行脚本,你将看到一个包含每个单词及其计数的字典,例如:{'python': 2, 'is': 2, 'a': 1, ...}。
Step 4: 排序并输出结果
我们已经拿到了词频字典,但它是无序的。我们需要按计数值(value)对字典进行降序排序。
# ... (之前的代码不变) ...
# --- 主程序入口 ---
if __name__ == '__main__':
file_path = 'article.txt'
top_n = 5 # 前 5 个 词频最高的词
text_content = read_file(file_path)
word_freq = count_words(text_content)
# 对字典按值进行排序
# word_freq.items() 将字典转为 (key, value) 元组的列表
# sorted() 函数进行排序
# key=lambda item: item[1] 指定按每个元组的第二个元素(也就是词频)排序
# reverse=True 表示降序
sorted_words = sorted(word_freq.items(), key=lambda item: item[1], reverse=True)
# 输出前 N 个结果
print(f"文件 '{file_path}' 中词频最高的 {top_n} 个单词是:")
for word, count in sorted_words[:top_n]:
print(f"- {word}: {count}")
知识点:
sorted()函数: 一个强大的内置排序函数,可以对任何可迭代对象进行排序。dict.items(): 返回一个包含字典所有(键, 值)对的视图对象。lambda函数: 一种小巧的匿名函数。lambda item: item[1]定义了一个函数,它接收一个参数item(在这里是一个(word, count)元组),并返回item的第二个元素item[1](也就是count)。sorted函数使用这个返回值作为排序的依据。这在 Python 中是极其常见的用法。- 列表切片
[:top_n]: 这是获取列表前top_n个元素的简洁方式。
Step 5: 整合与优化 - 命令行参数与 collections.Counter
我们的脚本已经很不错了,但还可以变得更专业、更 Pythonic!
- 处理命令行参数: 使用
sys.argv来获取用户在命令行中输入的文件名和数量。 - 使用
collections.Counter: Python 标准库的collections模块提供了一个专门用于计数的类Counter,它可以让我们的count_words函数变得更加简单。
最终版 word_counter.py:
import sys
import re
from collections import Counter
def main():
# 1. 解析命令行参数
if len(sys.argv) != 3:
print("使用方法: python word_counter.py <文件路径> <数量N>")
sys.exit(1)
file_path = sys.argv[1]
try:
top_n = int(sys.argv[2])
except ValueError:
print("错误: 数量N必须是一个整数。")
sys.exit(1)
# 2. 读取文件
try:
with open(file_path, 'r', encoding='utf-8') as file:
text = file.read()
except FileNotFoundError:
print(f"错误: 文件 '{file_path}' 未找到。")
sys.exit(1)
# 3. 文本清洗和分割
text = text.lower()
text = re.sub(r'[^a-z0-9\s]', ' ', text)
words = text.split()
# 4. 使用 Counter 进行词频统计
word_counts = Counter(words)
# 5. 获取最常见的 N 个单词
# Counter.most_common(n) 是一个非常方便的方法
top_words = word_counts.most_common(top_n)
# 6. 打印结果
print(f"文件 '{file_path}' 中词频最高的 {top_n} 个单词是:")
for word, count in top_words:
print(f"- {word}: {count}")
if __name__ == '__main__':
main()
知识点:
sys.argv: 一个列表,包含了所有命令行参数。sys.argv[0]是脚本名本身,sys.argv[1]是第一个参数,以此类推。collections.Counter: 一个特殊的字典子类。你可以直接用一个列表来初始化它,它会自动完成计数。Counter对象还有一个极其方便的.most_common(n)方法,直接返回一个按频率排序的、包含前n个元素的(元素, 计次)元组列表。这完美地替代了我们之前手动的排序和切片操作。
现在,你可以真正地像我们开始时设想的那样运行它了!
# 运行命令
python word_counter.py article.txt 5
# 预期输出
文件 'article.txt' 中词频最高的 5 个单词是:
- python: 2
- is: 2
- a: 1
- high: 1
- level: 1
Day 1 总结
恭喜你!你已经完成了第一天的挑战,并构建了一个功能完整的 Python 工具。
回顾一下今天你掌握的 Pythonic 知识点:
- 文件操作:
with open(...)是处理资源的最佳实践。 - 核心数据结构: 灵活运用
list和dict。 - Lambda 函数: 在
sorted()等函数中作为key参数,是高阶函数的体现。 - 标准库:
sys用于系统交互,re用于正则,而collections.Counter则是特定场景下的效率神器。学会利用标准库是 Python 开发的关键。 - 代码结构:
if __name__ == '__main__':是组织可执行脚本的标准模式。
今天我们从基础的文件和文本操作入手,感受了 Python 代码的简洁。你已经迈出了坚实的一步!
明日预告
第二天,我们将把难度稍微提升一点。我们将利用今天学到的知识,加上强大的 第三方库,亲手打造一个简单的 网络爬虫,从真实的网站上抓取并分析数据!
敬请期待!如果你有任何问题,欢迎在评论区留言讨论。
576

被折叠的 条评论
为什么被折叠?



