for line in file比readlines()快得多,因为后者一次性将整个文件加载进内存,易致MemoryError;前者是惰性读取,每次仅读一行(实际按缓冲区块),内存占用恒定几KB。

为什么用 for line in file 比 readlines() 快得多
因为 readlines() 会一次性把整个文件加载进内存,遇到 GB 级文本(比如日志、CSV、FASTA)极易触发 MemoryError 或拖慢系统。而文件句柄本身是迭代器,for line in file 是惰性读取——每次只从磁盘读入一行(实际是缓冲区大小的块,但对用户透明),内存占用恒定在几 KB。
实操建议:
- 永远优先用
with open(path) as f: for line in f:,不要碰readlines()或read().split(' ') - 确认编码:大文件常含 BOM 或混合编码,加
encoding='utf-8-sig'可自动剥离 UTF-8 BOM - 若需跳过空行或注释行,直接在循环内用
if not line.strip() or line.startswith('#'):过滤,别先读全再筛
逐行处理时如何避免 line 带换行符导致逻辑出错
for line in f 返回的每行末尾都含
(Windows 下可能是
),这会让 line == 'abc' 永远为 False,也影响 len(line) 和正则匹配。
实操建议:
- 统一用
line.rstrip(' ')替代line.strip()—— 后者会误删行首尾空格/制表符,破坏原始格式 - 如果后续要写回文件,保留原换行符更安全:先用
line.endswith(' ')判断,再决定写' '还是' ' - 用
repr(line)快速调试:看到'hello\n'就知道没清理,看到'hello'才算干净
当需要按块读取(如每 1000 行做一次聚合)时怎么写才不丢数据
直接用 enumerate 计数再分组容易在文件末尾凑不够 1000 行就丢掉剩余行;用 itertools.islice 虽然简洁,但多次调用会跳过中间内容。
实操建议:
- 用列表暂存当前批次:
batch = []; for line in f: batch.append(line.rstrip(' ')); if len(batch) == 1000: process(batch); batch.clear() - 循环结束后别忘处理余量:
if batch: process(batch) - 若批次处理耗时长,考虑用
yield改造成生成器函数,避免大列表累积内存
用 buffering=8192 或更大值真能提速?什么情况下反而变慢
Python 默认缓冲区是 8192 字节,对纯文本足够。增大缓冲区(如设为 buffering=65536)可减少系统调用次数,在机械硬盘或网络文件系统上有效;但在 SSD 或小行文件(平均行长
实操建议:
- 先用
time python script.py测基线,再改buffering对比;别盲目调大 - Linux 下可用
strace -e trace=read python script.py 2>&1 | grep read看实际系统调用次数是否下降 - 真正瓶颈常在 Python 层解析(如
json.loads、正则),此时优化 I/O 缓冲意义不大,应聚焦算法或用ujson/regex加速
文件句柄迭代器本身足够轻量,但“逐行”不等于“无脑逐行”——换行符处理、批次边界、缓冲策略这些细节,稍不注意就会让本该秒级完成的任务卡住几分钟。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











