2010-08-10 77 views
2

我在一個相當大的txt文件做一個文本搜索(10萬線,7mo) 文本並不大,但我需要大量的搜索。 我想尋找一個目標字符串,並返回它出現的那一行。 我的文本文件被格式化,以便目標只能出現在一行中。最快的文本搜索方法文件

什麼是最有效的方法?我做了很多搜索,所以我想提高速度。 這裏現在是mycode的:

def lookup_line(target): 
    #returns line of the target, or None if doesnt exist 
    line=None 
    dir=os.path.dirname(__file__) 
    path=dir+'/file.txt' 
    file=open(path,'r') 
    while line==None: 
     l=file.readline() 
     l=unicode(l,'utf-8') 
     if target in l: 
      break 
     if l=='': break #happens at end of file, then stop loop 
    line=l 
    if line=='':line=None #end of file, nothing has been found 
    file.close() 
    return line 

我用這個Python代碼爲谷歌的AppEngine應用。

謝謝!

+0

您是否在搜索單詞,短語或時髦的標點符號(如編譯器錯誤)?文件是否在搜索之間改變? – sje397 2010-08-10 13:32:40

+0

我正在搜索非拉丁字符中的單詞。 格式是:「你好[」 這是由於文件格式化,我需要2個空格和[以確保該單詞在行中的正確位置找到。 – user375348 2010-08-10 13:43:50

回答

11
  1. 負荷一下子整個文本在RAM中。不要逐行閱讀。
  2. 搜索blob中的模式。如果找到它,請使用text.count('\n',0,pos)獲取行號。
  3. 如果您不需要行號,請查找上一個和下一個EOL以將該行剪切掉。

Python中的循環是緩慢的。字符串搜索速度非常快。如果您需要查找多個字符串,請使用正則表達式。

如果這不夠快,使用像grep外部程序。

1

首先,不要明確解碼字節。

from io import open 

其次,考慮這樣的事情。

with open(path,'r',encoding='UTF-8') as src: 
    found= None 
    for line in src: 
     if len(line) == 0: break #happens at end of file, then stop loop 
     if target in line: 
      found= line 
      break 
    return found 

這可以略微簡化的使用return Nonereturn line代替break。它應該更快地運行一次頭髮,但在有多次退貨時進行更改會稍微困難一些。

3

如果您一遍又一遍地搜索相同的文本文件,請考慮索引文件。例如,創建一個字典,將每個單詞映射到它所在的行上。這將需要一段時間來創建,但會進行搜索O(1)。

如果您正在搜索不同的文本文件,或者不能索引出於某種原因該文件,你可能不會得到任何比KMP algorithm更快。

編輯:我描述了將只對單個詞的搜索,而不是多字的搜索工作指數。如果你想搜索多個單詞(任何字符串),那麼你可能無法索引它。

+0

好的建議,你可以編寫一個算法,將一個單詞索引做多詞搜索。多詞索引很可能會浪費時間。此外,您可以將字邊界的字符存儲爲索引。正則表達式會使這個任務變得微不足道。 – marr75 2010-08-10 13:46:28

+0

好點。至少可以很容易地確定一行是否包含句子中的所有單詞。不過,我不認爲搜索詞的部分內容(例如「uick brown fo」)將以有意義的方式進行索引。 – 2010-08-10 14:00:43

相關問題