Python:获取大文件中所有行的行指针

3

我有一个很大的文件(6-60 GB),无法完全加载到内存中。 我可以逐行读取:

with open(...) as f:
    for line in f:
        # Do something with 'line'

但是有时候当我读到第n行的时候,我也需要从第n+2行获取信息。当我的“line”对象指向第n行时,我该如何读取第n+2行?我仍然需要正常处理后面的行。
我担心如果使用“f.readlines(10)”,因为我不知道我的前瞻大小(可能是99)。
我想过一种方法,就是在一个列表中为每一行设置指针,使用“seek”和“tell”,但我又担心存储空间问题。
在阅读此文件时,我寻求速度优先。 有什么建议吗?

你可能需要读取几行并至少存储+4行,如果你知道每行大致的长度,我强烈建议使用f.read(line_length*4),然后执行buffer_lines = f.read(line_length*4).split()。尽可能多地利用.seek()来跳转。正如@Prune所说,最好使用已知引用的字典或列表,可以是纯粹的dict或轻量级数据库(例如sqlite或postgresql)。 - Torxed
@Torxed,我不知道n在哪里的问题与您所建议的有关。 - azazelspeaks
你能使用任何限制吗?例如,你只需要查看即将到来的行,或者可能从任何方向上永远不超过100行? - Sam Mason
只需要看接下来的几行。 - azazelspeaks
2个回答

3
你提出的行参考点子不错,并且在存储方面非常有效:一个整数可以指向每一行。但是,在文件中跳来跳去并不特别高效。
相反,我建议你拥有一个预读缓冲区。如果你在第n行并且需要第n+2行的数据,那么预先读取这两行并将其保存在内存中。完成处理第n行。当你准备好下一行输入时,你已经在缓冲区中了。
读取顺序为(a)缓冲区;(b)从内存获取下一行。
这样讲清楚了吗?

我该如何在Python中实现这个? - azazelspeaks
1
一个简单的列表就能完成所有这些:https://docs.python.org/2/tutorial/datastructures.html - Newtopian
1
这里没有“查找”功能--您按顺序读取行,将它们放入缓冲区(队列)中。您可以预先读取需要处理的给定行。当您完成该行时,从队列中删除它并继续进行下一步。您可以在网上搜索此类预读队列。要求我们提供代码而不显示您的尝试超出了Stack Overflow的范围。 - Prune

2
作为Prune答案的必然结果,一个队列可以很好地实现预读缓冲区或向后查看,两个保持恒定长度的队列可以提供当前行周围的良好中间视图。
基本上,读取一行,推入队列。当堆栈达到一定大小时,从队列弹出并处理,然后推入第二个队列。当第二个队列达到给定大小时,只需从中弹出并忘记该行。每当您需要查看当前行周围时,只需访问任一队列中的值即可。
实际上,所有这些都可以通过一个简单的列表来完成 https://docs.python.org/2/tutorial/datastructures.html 要将列表用作预读队列, _l.insert(0, line) 来插入一行 _l.pop() 来删除该行并处理它
或者
_l.append(line) 来插入一行 _l.pop(0) 来删除该行并处理它
确保在调用pop之前_list达到所需的大小,这仅适用于需要保留在内存中的行接近您要处理的行。

这可能是我要做的,list.append()和list.pop()。谢谢。等待看看是否有其他答案,否则我将把它标记为解决方案。 - azazelspeaks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接