首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >对大型文件进行反向迭代的有效方法

对大型文件进行反向迭代的有效方法
EN

Stack Overflow用户
提问于 2016-08-02 14:58:14
回答 2查看 1.4K关注 0票数 0

我试图迭代一个非常大的、不断变化的文件(通常大约150万行),并对每一行执行操作。这是一个日志文件,因此在文件末尾追加新行。我的程序将允许用户指定每一行必须匹配的参数,并返回最近的匹配。因此,我希望从文件的末尾开始,并努力提高程序的效率(而不是列出一行代码并将其反转)。

下面是一个例子:

代码语言:javascript
代码运行次数:0
运行
复制
2016-01-01 01:00 apple

2016-01-02 05:00 banana

2016-01-03 03:00 apple

2016-01-04 00:00 apple

2016-01-05 12:00 banana

如果用户请求1行与"apple“匹配,我想返回"2016-01-04 00:00苹果”,这是最接近文件末尾的行。当只有五行时,这并不困难,但是当有数以百万计的行时,性能就会受到影响。我尝试使用tail -n [file size]在文件末尾开始,但是这个方法不能很好地扩展;我不能使用迭代来提高性能(如果结果是文件中的最后一行,我不想迭代1,500,000行)。

我尝试过的另一种方法是将文件分解为“块”:

代码语言:javascript
代码运行次数:0
运行
复制
|
| Remaining lines
|

...

|
| Second group of n lines
|

|
| First group of n lines
|

然后,我将使用GNU sed只流每个块中的行。然而,我发现程序的性能几乎没有改善(当n较小时,实际上受到了影响)。

是否有更好的方法(在迭代文件的同时最小化运行时间)?我一直在使用Linux命令行中的其他程序(通过“子进程”),但是使用Python内置的内容可能会更好。我非常感谢任何能引导我走向正确方向的信息。

我使用Linux访问Python2.7.3、2.7.10、2.7.11-c7、3.3.6和3.5.1。

EN

回答 2

Stack Overflow用户

发布于 2016-08-02 15:05:27

打开文件后,可以使用文件句柄的seek(bytes, start_point)方法跳过文件中的任意位置,以若干字节表示。例如:

代码语言:javascript
代码运行次数:0
运行
复制
with open(my_file) as f:
    f.seek(1024, 0)
    for line in f:
        print(line)

这将打印文件中的每一行,但第一个千字节除外。如果您提供了一个负数,它将返回,并且向第二个参数提供一个2值将使它从文件的末尾开始计数。因此,调用f.seek(-1024, 2)将导致上面只打印文件的最后一千字节。

当文件小于您的块大小时,可能需要一些安全措施来防止其死亡,但我就是这样做的。(如果您需要进一步追溯,这也非常简单:只需再次调用seek即可。)

票数 0
EN

Stack Overflow用户

发布于 2016-08-02 15:08:22

您可以使用:

代码语言:javascript
代码运行次数:0
运行
复制
for line in reversed(open("filename").readlines()):
    print line.rstrip()

在Python 3中:

代码语言:javascript
代码运行次数:0
运行
复制
for line in reversed(list(open("filename"))):
    print(line.rstrip())

这里已经回答了这个问题:Read a file in reverse order using python

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

https://stackoverflow.com/questions/38723957

复制
相关文章

相似问题

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