使用Python在大文件中查找单词的最后一次出现

6
我是一位有用的助手,可以为您提供翻译。以下是需要翻译的内容:

我有一个非常大的文本文件。我想要搜索特定单词的最后一个出现位置,然后对其后面的行执行某些操作。

我可以这样做:

if "word" in line.split():
    do something

但是,我只对最后一次出现的"word"感兴趣。


4
根据文件大小,您可能希望从末尾开始分块读取,并向后查找。 - user2357112
https://docs.python.org/3/library/stdtypes.html#str.rfind 谷歌是你的好朋友。 - Tim
你的文件有多大? - Bonifacio2
@Bonifacio2:大约有300k行。 - hat
使用 .rfind('word') 运算符 - Assem Mahrous
5个回答

7

一个更简单且更快的解决方案是以相反顺序打开文件,然后搜索第一个单词的位置。

在Python 2.6中,您可以执行以下操作(其中word是要查找的字符串)

for line in reversed(open("filename").readlines()):
    if word in line:
    # Do the operations here when you find the line

5
如果文件大小为数百兆甚至几个G,您可能想使用mmap,这样就不必将整个文件读入内存。rfind方法可在文件中查找字符串的最后一个出现位置。
import mmap

with open('large_file.txt', 'r') as f:
    # memory-map the file, size 0 means whole file
    m = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ)  
                          # prot argument is *nix only

    i = m.rfind('word')   # search for last occurrence of 'word'
    m.seek(i)             # seek to the location
    line = m.readline()   # read to the end of the line
    print line
    nextline = m.readline()

只需不断调用readline()来读取后续行。

如果文件非常大(例如数十GB),则可以使用mmap()lengthoffset参数将其分块映射。


我刚试了一下,m.rfind(word.encode()) 返回的数字似乎不是行号,而可能是文件中的字节位置? - AeroClassics
是的,没错,rfind() 函数会返回文件中的字节位置,而不是行号。 - Andy Madge
OP并没有要求行号,他们只想处理最后一次匹配之后的行。 - Andy Madge

4
试试这样做:
f = open('file.txt', 'r')
lines = f.read()
answer = lines.find('word')

然后你可以从中选择最后一个单词

您还可以使用str.rfind方法。

str.rfind(sub[, start[, end]])

返回字符串中子字符串sub的最高索引,该子字符串包含在s [start:end]内,其中可选参数start和end被解释为切片符号中的范围。如果失败,则返回-1。

这与 OP 所做的不完全相同。将 "name" in "protect your enamel".split()"protect your enamel".rfind("name") 进行比较。 - DSM
@user3414693:大约有300k行。 - hat
@hat:是的,所以你不想将其全部读入内存,是的,你必须按顺序读取它。 - user3414693

2
你可以打开文件,将其转换为列表,反转其顺序并循环查找你的单词。
with open('file.txt','r') as file_:
    line_list = list(file_)
    line_list.reverse()

    for line in line_list:
        if line.find('word') != -1:
            # do something
            print line

可选地,您可以通过将缓冲区大小(以字节为单位)作为 open 的第三个参数来指定文件缓冲区的大小。例如:with open('file.txt','r', 1024) as file_:


0
如果您的文件太大而无法在内存中打开,并且您要查找的单词更有可能在文件的后半部分中找到,那么您可以使用file_read_backwards库来反向读取文件。
from file_read_backwards import FileReadBackwards

with FileReadBackwards(filename, encoding="utf-8") as frb:
    for line in frb:
        if word in line:
            # Do something 

其中filename包含文件名,word是你要查找的字符串。


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