学径XUEJING · 个人学习平台通知设置

课程库 AI 主线 文件与自动化脚本 › 第 2

处理 CSV —— 用标准库读表格数据

普通课55 分钟

本课导读

打开任何一家公司的共享盘,最多的数据文件八成是 Excel 表。而 Excel 表的"素颜形态"——CSV(逗号分隔值),是数据交换的通用货币:导出报表、下载账单、对接系统,到处是它。本课用标准库 csv 模块把表格数据读进 Python、算完再写回去——这也是 U1.5 pandas 的前置直觉:先懂"表格数据长什么样",再学豪华工具。预计 55 分钟。

CSV:Excel 卸了妆

CSV 文件本质就是纯文本:第一行是表头,之后每行一条记录,字段用逗号隔开。先造一份看看:

Python

既然是文本,line.split(",") 手动切不就行了?先别——真实数据里字段本身可能含逗号(比如产品名"键盘,机械"会被 Excel 存成 "键盘,机械"),手动 split 直接切碎。标准库的 csv 模块懂全部规则,这轮子别自己造。

csv.reader:按行切好端给你

Python
  • csv.reader(f) 把文件变成"一行行列表"的流水线,直接 for
  • 表头也是普通一行——通常用 next(reader) 先取走它(下面示范)
  • open 里多了个 newline="":处理 CSV 的固定搭配(防止 Windows 下多出空行),先记住照抄

大坑预警:读出来的全是字符串

Python

CSV 里没有数字,只有长得像数字的字符串——"299" 不是 299。要算账先 int()/float() 转换,转换可能失败(脏数据),异常课的气囊随时候命。这个坑在 pandas 里会被自动处理,但你得先知道它存在,才懂 pandas 帮了你什么。

csv.DictReader:每行变字典(推荐主力)

按下标取列(row[2])容易错还难读。DictReader 自动拿表头当键,每行给你一个字典——U1.1 的功夫直接平移过来:

Python

看到了吗——"字典的列表"正是 U1.1 说的真实数据的标准形状。CSV 读进来是它,下一课的 JSON 解析出来还是它。形状统一,功夫通用。

csv.writer:算完写回去

Python

writer.writerow(列表) 一次写一行,逗号和引号它替你操心。到这里,"读 → 加工 → 写"三段式的 CSV 版你已经齐活:读账单 → 算汇总 → 出报表,这就是无数行政、运营岗位每周手工干几小时的活——你现在会让它一秒完成了。

说明

和 Excel 的关系:CSV 用 Excel 打开就是表格,Excel 也能"另存为 CSV"。所以这套功夫的实战流程往往是:同事给你 Excel → 另存 CSV → Python 加工 → 产出 CSV → 用 Excel 打开交差。等 U1.5 的 pandas 上场,连"另存"这步都能省。

✍️ 练习

练习 1:考勤统计

读出考勤表,统计迟到(status 为"迟到")的总人次并打印是谁、哪天。

Python
✅ 参考答案
import csv

with open("attendance.csv", encoding="utf-8", newline="") as f:
    late = [r for r in csv.DictReader(f) if r["status"] == "迟到"]

print(f"迟到共 {len(late)} 人次")
for r in late:
    print(f'{r["date"]} {r["name"]}')

练习 2:工资条生成器

按底薪加提成算实发(实发 = base + sales × 0.05),把结果写成新表 payroll.csv(表头 name,pay),再读出来打印验证。

Python
💡 提示

读的时候 base 和 sales 都是字符串,先 int()。算完 writerow(["name", "pay"]) 打头,逐行写 [名字, 实发]。

✅ 参考答案
import csv

with open("staff.csv", encoding="utf-8", newline="") as f:
    staff = list(csv.DictReader(f))

with open("payroll.csv", "w", encoding="utf-8", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["name", "pay"])
    for s in staff:
        pay = int(s["base"]) + int(s["sales"]) * 0.05
        writer.writerow([s["name"], int(pay)])

with open("payroll.csv", encoding="utf-8") as f:
    print(f.read())

练习 3:脏数据幸存者(挑战)

这份表的 amount 列混进了脏值。统计能转成数字的总额,脏行收集起来单独打印(一行都不能让程序崩)。U1.1 异常课的"逐条 try、坏的隔离"模式复出。

Python
✅ 参考答案
import csv

total = 0
bad_rows = []
with open("dirty.csv", encoding="utf-8", newline="") as f:
    for r in csv.DictReader(f):
        try:
            total = total + int(r["amount"])
        except ValueError:
            bad_rows.append(r)

print(f"有效总额:{total} 元")
print("待人工处理:")
for r in bad_rows:
    print(f'  {r["product"]}: {r["amount"]}')

真实报表十有八九有脏行——"好的继续、坏的隔离、最后人工看"是数据清洗的职业素养,U1.5 的 pandas 清洗课会把它工业化。

📝 随堂测验

随堂测验0 / 5 题正确

1. 为什么不用 line.split(",") 手动解析 CSV,而用 csv 模块?

2. csv 读出的 "299",直接拿去加 100 会怎样?

3. csv.DictReader 相比 csv.reader 的优势是?

4. 用 csv 模块时,open 的固定搭配是?

5. 把统计结果写成 CSV,正确的动作是?

本课小结

  • CSV = 表头 + 逗号分隔的纯文本,Excel 的素颜;解析交给标准库 csv 模块,别手动 split
  • 读出来全是字符串——算账先 int()/float(),脏数据用 try 隔离
  • 主力姿势 csv.DictReader:每行一个字典,"字典的列表" = 数据的标准形状
  • 写表用 csv.writer + writerow;open 固定搭配 encoding="utf-8", newline=""

下一课是 CSV 的表亲、API 时代的通用语言——JSON。U1.1 埋的"嵌套结构"伏笔,正式收网。

划选正文任意文字可高亮、批注或加入复习卡

讨论

载入中…