如何用Python每次读取文件的两行?
我正在编写一个Python脚本,用来解析一个文本文件。这个文本文件的格式是每个元素占用两行。为了方便起见,我想在解析之前先读取这两行。请问在Python中可以这样做吗?
我想做的事情类似于:
f = open(filename, "r")
for line in f:
line1 = line
line2 = f.readline()
f.close
但是这样做会出错,提示信息是:
ValueError: 混合使用迭代和读取方法会导致数据丢失
相关内容:
14 个回答
使用 next()
函数,比如:
with open("file") as f:
for line in f:
print(line)
nextline = next(f)
print("next line", nextline)
....
import itertools
with open('a') as f:
for line1,line2 in itertools.zip_longest(*[f]*2):
print(line1,line2)
itertools.zip_longest()
是一个返回迭代器的函数,所以即使文件有数十亿行,它也能很好地工作。
如果行数是奇数,那么在最后一次迭代时,line2
会被设置为 None
。
在 Python2 中,你需要用 izip_longest
来代替。
在评论中,有人问这个方法是否会先读取整个文件,然后再第二次遍历文件。我认为不会。with open('a') as f
这一行是打开了一个文件句柄,但并没有读取文件。f
是一个迭代器,所以它的内容不会被读取,直到你请求它。zip_longest
接受迭代器作为参数,并返回一个迭代器。
确实,zip_longest
是对同一个迭代器 f 调用了两次。但实际上发生的事情是,第一次对第一个参数调用 next(f)
,然后对第二个参数也调用 next()
。因为 next()
是在同一个底层迭代器上调用的,所以会依次返回后续的行。这和一次性读取整个文件是非常不同的。实际上,使用迭代器的目的就是为了避免一次性读取整个文件。
因此,我相信这个方法按预期工作——文件只被 for 循环读取了一次。
为了验证这一点,我对比了使用 zip_longest
的方法和使用 f.readlines()
的方法。我在最后加了一个 input()
来暂停脚本,并分别运行了 ps axuw
:
% ps axuw | grep zip_longest_method.py
unutbu 11119 2.2 0.2
4520 2712 pts/0 S+ 21:14 0:00 python /home/unutbu/pybin/zip_longest_method.py bigfile
% ps axuw | grep readlines_method.py
unutbu 11317 6.5 8.8
93908 91680 pts/0 S+ 21:16 0:00 python /home/unutbu/pybin/readlines_method.py bigfile
从结果来看,readlines
显然是一次性读取了整个文件。由于 zip_longest_method
使用的内存明显更少,我认为可以安全地得出结论,它并没有一次性读取整个文件。
类似的问题可以在 这里找到。你不能把循环和逐行读取混在一起,所以你需要选择使用其中一种方式。
while True:
line1 = f.readline()
line2 = f.readline()
if not line2: break # EOF
...