我想逐行阅读文件,除了最后的N行。我如何知道在没有到达文件末尾和返回跟踪/丢弃最后N行的情况下,在Python中停止在哪里呢?要求#line= X和循环(X)是一种很好的方法吗?
最简单/最毕不过的方法是什么?
发布于 2014-11-02 11:12:29
三种不同的解决办法:
1)快速而肮脏的,见John的答案:
with open(file_name) as fid:
lines = fid.readlines()
for line in lines[:-n_skip]:
do_something_with(line)这种方法的缺点是必须先读取内存中的所有行,这可能是大文件的一个问题。
2)双程
处理该文件两次,一次用于计数n_lines行数,第二次传递时只处理第一批n_lines - n_skip行:
# first pass to count
with open(file_name) as fid:
n_lines = sum(1 for line in fid)
# second pass to actually do something
with open(file_name) as fid:
for i_line in xrange(n_lines - n_skip): # does nothing if n_lines <= n_skip
line = fid.readline()
do_something_with(line)此方法的缺点是必须对文件进行两次迭代,在某些情况下可能要慢一些。然而,好的是,你的记忆中从来没有超过一行。
3)使用缓冲区,类似于Serge的解决方案
如果您只想迭代文件一次,那么只有当您知道行i存在时,才能确定您可以处理行i + n_skip。这意味着您必须首先将n_skip行保存在临时缓冲区中。这样做的一种方法是实现某种FIFO缓冲区(例如,具有实现循环缓冲区的生成器功能):
def fifo(it, n):
buffer = [None] * n # preallocate buffer
i = 0
full = False
for item in it: # leaves last n items in buffer when iterator is exhausted
if full:
yield buffer[i] # yield old item before storing new item
buffer[i] = item
i = (i + 1) % n
if i == 0: # wrapped around at least once
full = True使用一系列数字进行快速测试:
In [12]: for i in fifo(range(20), 5):
...: print i,
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14在您的文件中使用此方法的方式:
with open(file_name) as fid:
for line in fifo(fid, n_skip):
do_something_with(line)请注意,这需要足够的内存来临时存储n_skip行,但这仍然比在第一个解决方案中读取内存中的所有行要好。
这3种方法中哪一种最好是在代码复杂度、内存和速度之间进行权衡,这取决于您的确切应用程序。
发布于 2014-11-02 10:32:54
除非您有办法预先知道实际行数,否则必须读取整个文件。
但是,我假设您希望逐行处理文件,但N行除外,您可以这样做,而不需要在内存中加载所有文件,并且只保留N行的列表:
with open(file) as fd:
lines = []
try:
for i in range(N):
lines.append(next(fd))
i = 0
for line in fd:
# process lines[i]
print (lines[i].rstrip())
lines[i] = line
i = (i + 1) % N
except StopIteration:
print "less than %d lines" % (N,)发布于 2014-11-02 08:30:13
要将所有行读到最后的X行,您需要知道最后X行从哪里开始。你会在某个地方需要这些信息。有几种方法可以获取这些信息。
https://stackoverflow.com/questions/26696393
复制相似问题