首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Python不读取文件最后N行的简单方法

用Python不读取文件最后N行的简单方法
EN

Stack Overflow用户
提问于 2014-11-02 05:34:45
回答 4查看 1.9K关注 0票数 2

我想逐行阅读文件,除了最后的N行。我如何知道在没有到达文件末尾和返回跟踪/丢弃最后N行的情况下,在Python中停止在哪里呢?要求#line= X和循环(X)是一种很好的方法吗?

最简单/最毕不过的方法是什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-11-02 11:12:29

三种不同的解决办法:

1)快速而肮脏的,见John的答案:

代码语言:javascript
复制
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行:

代码语言:javascript
复制
# 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缓冲区(例如,具有实现循环缓冲区的生成器功能):

代码语言:javascript
复制
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

使用一系列数字进行快速测试:

代码语言:javascript
复制
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

在您的文件中使用此方法的方式:

代码语言:javascript
复制
with open(file_name) as fid:
    for line in fifo(fid, n_skip):
        do_something_with(line)

请注意,这需要足够的内存来临时存储n_skip行,但这仍然比在第一个解决方案中读取内存中的所有行要好。

这3种方法中哪一种最好是在代码复杂度、内存和速度之间进行权衡,这取决于您的确切应用程序。

票数 2
EN

Stack Overflow用户

发布于 2014-11-02 10:32:54

除非您有办法预先知道实际行数,否则必须读取整个文件。

但是,我假设您希望逐行处理文件,但N行除外,您可以这样做,而不需要在内存中加载所有文件,并且只保留N行的列表:

代码语言:javascript
复制
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,)
票数 2
EN

Stack Overflow用户

发布于 2014-11-02 08:30:13

要将所有行读到最后的X行,您需要知道最后X行从哪里开始。你会在某个地方需要这些信息。有几种方法可以获取这些信息。

  1. 写入文件时,保存最后X行的位置。当到达那个位置时,停止阅读。
  2. 将行开始位置存储在某个位置,这允许附加到文件中。
  3. 你知道线的大小。
    1. 每一行都可以有相同的大小,然后从文件大小中计算它。
    2. 每行至少有一个字符,因此不需要读取最后一个X字符。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26696393

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档