有效的方法来反转迭代大文件

时间:2016-08-02 14:58:14

标签: python performance file loops io

我正在尝试迭代一个非常大的,不断变化的文件(通常大约1.5M行)并在每一行上执行操作。它是一个日志文件,因此在文件末尾添加了新行。我的程序将允许用户指定每行必须匹配的参数并返回最近的匹配。因此,我想从文件的末尾开始,然后努力使程序高效(而不是制作行列表并将其反转)。

以下是一个示例情况:

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 apple”,即最接近文件末尾的行。当只有五行时,这并不困难,但是当有数百万行时,性能会受到影响。我尝试使用tail -n [file size]从文件末尾开始,但这种方法不能很好地扩展;我不能使用迭代来提高性能(如果结果是文件中的最后一行,我不想迭代1,500,000行)。

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

|
| Remaining lines
|

...

|
| Second group of n lines
|

|
| First group of n lines
|

然后我会使用GNU sed来仅传输每个块中的行。然而,我发现该程序的性能几乎没有改善(并且当 n 较小时实际受到影响)。

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

我正在使用Linux访问Python 2.7.3,2.7.10,2.7.11-c7,3.3.6和3.5.1。

2 个答案:

答案 0 :(得分:0)

打开文件后,可以使用文件句柄的var num1: String = numberresult [0] var num2: String = numberresult [1] 方法跳转到文件中的任意位置,用多个字节表示。例如:

seek(bytes, start_point)

这将打印文件中的每一行,第一个千字节除外。如果你提供一个负数,它将向后,并且向第二个参数提供值with open(my_file) as f: f.seek(1024, 0) for line in f: print(line) 将使它从文件末尾开始计数。因此,调用2会导致上面只打印文件的最后一个字节。

当文件小于块大小时,可能需要一些安全措施来防止它死亡,但这就是我的方法。 (如果事实证明你需要更进一步,那也很简单:只需再次拨打f.seek(-1024, 2)。)

答案 1 :(得分:0)

您可以使用:

for line in reversed(open("filename").readlines()):
    print line.rstrip()

在Python 3中:

for line in reversed(list(open("filename"))):
    print(line.rstrip())

这已在这里得到解答:Read a file in reverse order using python