
本文介绍如何使用 python 的 csv.dictreader 流式读取制表符分隔的 csv 文件,按需解析出生年份并实时计算客户年龄中位数,避免内存溢出和 typeerror('_csv.reader' object is not subscriptable)错误。
在处理大型 CSV 文件时,一个常见误区是试图像操作字典一样直接通过键(如 data['birth_year'])访问 csv.reader 返回的行对象——但 csv.reader 每次返回的是列表(list),而非字典,因此不支持键下标访问,从而抛出 TypeError: '_csv.reader' object is not subscriptable。
正确做法是改用 csv.DictReader:它会自动将首行(header)解析为字段名,并将后续每一行映射为一个以字段名为键的字典,使代码语义清晰、可读性强,且仍保持逐行流式读取——即内存占用恒定,与文件大小无关。
以下是优化后的完整实现:
import csv
from statistics import median
def median_age(filename):
with open(filename, 'r', encoding='utf-8') as file:
reader = csv.DictReader(file, delimiter='\t')
# 构建生成器表达式:对每一行动态计算年龄,不构建中间列表
customer_ages = (2024 - int(row['birth_year']) for row in reader)
return median(customer_ages)✅ 关键要点说明:
- 使用 csv.DictReader 替代 csv.reader,天然支持 row['birth_year'] 访问;
- 生成器表达式 (... for row in reader) 确保数据按需计算、零缓存,适合 GB 级日志或客户档案;
- 显式指定 encoding='utf-8' 防止中文路径或特殊字符引发解码错误(推荐实践);
- 无需手动调用 next(reader) 跳过表头——DictReader 自动完成;
- statistics.median() 可直接接受生成器(Python ≥3.10),内部自动转换为有序序列计算中位值。
⚠️ 注意事项:
- 确保 CSV 文件首行为有效字段名,且包含精确匹配的 'birth_year' 列(区分大小写与空格);
- 若存在缺失或非数字的 birth_year 值,建议添加异常处理(如 try/except ValueError)提升鲁棒性;
- 年份硬编码 2024 在生产环境应替换为 datetime.date.today().year 以保证时效性。
该方案兼顾简洁性、内存效率与工程健壮性,是处理大规模结构化文本数据的标准范式之一。










