最稳妥的方式是用 itertools.islice,因为 readlines()[n:] 会将整个文件加载进内存,大文件时易引发 MemoryError、程序卡死或系统频繁 swap。

直接跳过前N行最稳妥的方式是用 itertools.islice,而不是 readlines()[n:]——后者会把整个文件一次性加载进内存,大文件时容易爆内存。
为什么 readlines()[n:] 在大文件里很危险
调用 readlines() 会把所有行读入内存生成一个大列表。哪怕你只想要第10001行开始的内容,Python 也得先把前面1万行全塞进 RAM。遇到几百 MB 的日志或 CSV,很容易触发 MemoryError 或拖慢整机响应。
常见错误现象:MemoryError、程序卡死、系统开始疯狂 swap。
-
readlines()适合小文件( - 如果文件编码不统一(比如含 BOM 或混合 \r\n/\n),
readlines()还可能因解码失败中断 - 切片
[n:]本身不报错,但掩盖了底层一次性加载的问题
用 itertools.islice 真正实现“跳过”而非“丢弃”
islice 是迭代器友好的跳过方式:它不会预读全部内容,而是让文件对象逐行推进,跳过前 N 行后才开始真正消费数据。内存占用恒定,和文件大小无关。
立即学习“Python免费学习笔记(深入)”;
实操建议:
- 必须配合
with open(...)使用,确保文件句柄及时释放 - 跳过行数用
islice(f, n, None),注意第二个参数是起始索引,第三个是结束(None表示到末尾) - 如果说明行不固定(比如以
#或//开头),就别硬写数字,改用循环 +next()或itertools.takewhile
示例:跳过前3行读取剩余内容
from itertools import islice
<p>with open("data.txt", encoding="utf-8") as f:
for line in islice(f, 3, None):
print(line.rstrip())
当说明行格式不固定时:用循环 + next() 更灵活
比如说明块可能有空行、注释行、版本信息行,长度不一。这时候硬写 islice(f, 5, None) 容易错漏。
推荐做法是手动推进文件指针,直到遇到第一个“有效数据行”(比如非空、不含 #、能被 csv.reader 正常解析等):
- 用
next(f)逐行跳过,配合try/except StopIteration防止越界 - 判断条件写清楚,例如
line.strip() and not line.startswith("#") - 一旦找到首行数据,就把当前
f传给后续处理(如csv.reader(f)),避免重复读取
示例:跳过所有以 # 或空行开头的说明行
with open("config.txt", encoding="utf-8") as f:
# 跳过说明块
for line in f:
if line.strip() and not line.strip().startswith("#"):
# 当前行是首条有效数据,保留它
first_data_line = line
break
else:
raise ValueError("no data line found")
<pre class="brush:php;toolbar:false;"># 继续读取剩余行(包括刚读到的 first_data_line)
lines = [first_data_line] + list(f)
真正难的不是“怎么跳过”,而是“怎么定义什么是该跳过的行”——业务逻辑决定跳过策略,工具只是执行者。别在没理清说明行边界规则前,就急着套 islice 或切片。


















