Python-快速文件搜索
我有一个文件,有大量(0.5-150万)行,每行都是一个文件名(长度约为50-100个字符)。我需要的是通过给定的查询快速搜索这些行。现在,我的代码如下所示:Python-快速文件搜索,python,search,indexing,python-3.x,Python,Search,Indexing,Python 3.x,我有一个文件,有大量(0.5-150万)行,每行都是一个文件名(长度约为50-100个字符)。我需要的是通过给定的查询快速搜索这些行。现在,我的代码如下所示: def similarity(haystack, needle): words = re.findall(r'\w+', haystack.lower()) # replacing by split with separators reduces time by about 4 seconds for word in w
def similarity(haystack, needle):
words = re.findall(r'\w+', haystack.lower()) # replacing by split with separators reduces time by about 4 seconds
for word in words:
if word == needle:
return 10
for word in words:
if word.startswith(needle):
return 10 ** (len(needle) / len(word))
if needle in haystack:
return 1
return 0
def search(text):
text = text.lower()
lines = [(similarity(x, text), x) for x in lines]
return [x[1] for x in sorted(lines, reverse = True)[:15]]
它在我的PC上的示例文件上运行大约15秒(几乎所有时间都在similarity()
函数中),我希望它能在几秒钟内立即运行。如何做到这一点
我认为索引可能会有所帮助,但不知道它可能的结构。而且,如果可能的话,我希望搜索更加模糊-例如,使用N-gram或类似的东西。但现在主要关注的是速度
UPD:
对相同的行
进行多次搜索
needle
始终是一个单词
“更模糊”意味着即使pinder
有点输入错误,它也应该找到行
10**(len(t)/len(word))
def similarity(haystack, needle):
if needle not in haystack:
return 0
words = haystack.lower().split()
if needle in words:
return 10
for word in words:
if word.startswith(needle):
return 10 ** (len(needle) / len(word))
return 1
因为您使用的是同一个文件来搜索字符串。如果使用持久字典,可以加快搜索速度 考虑到你的逻辑。你可以用这个
import shelve
import os
PERSISTENT_DICT_FILENAME = "my_persistent_dict"
def create_a_persitant_dict(haystack_filename):
pd = shelve.open(PERSISTENT_DICT_FILENAME)
f = open(haystack_filename)
for filename in f:
filename_len = len(filename)
filename = filename.lower()
for i in range(1,filename_len):
partial_filename = filename[:i]
calculation = 10 ** ((len(partial_filename)*1.0)/filename_len)
if pd.has_key(partial_filename):
if calculation > pd[partial_filename]:
pd[partial_filename] = calculation
else:
pd[partial_filename] = calculation
pd.close()
def search_string(needle):
needle = needle.lower()
pd = shelve.open(PERSISTENT_DICT_FILENAME)
if pd.has_key(needle):
return_val = pd[needle]
else:
return_val = 0
pd.close()
return return_val
if __name__ == "__main__":
#create_a_persitant_dict("a_large_file.txt")
needle = raw_input("Enter the string to search")
print search_string(needle)
说明:
create_a_persitant_dict(haystack_filename)
将创建一个读取大文件的持久字典。键是在文件中找到的字符串(例如:如果文件中的一行是“World.txt”,则键将是“w”、“wo”、“wor”、“worl”…等,值是每个键的计算值(10**等)
这只是一次昂贵的操作,但目的是加快搜索速度
search_string(needle)
该函数将在持久性字典中搜索字符串,并根据您的逻辑进行计算。它将比每次迭代都要快。1.当然,在这之前有
返回值
。2.好的,将名称更改为更有意义的名称。3.一行不太可能包含一次以上出现的指针
。这是错误的这是一个明显的优化,但它确实有帮助=)谢谢,现在它在2-3秒内执行。顺便说一句,这不是一个使搜索“更模糊”的简单方法吗?@Chersaya:简单,不。比这更模糊需要查找搜索字符串等的部分。这最好通过词干词典等来完成,然后进入全文搜索引擎模式。事实上,有一个简单的方法可以做到这一点:使用全文搜索引擎然而,写一个并不简单。你会建议使用什么引擎呢?据我所知,它们中的大多数用于搜索包含某种模式的文件,而不是搜索单个文件中的一行。我建议不要重新发明轮子,使用专用的全文搜索引擎,如。我尝试过建立反向索引,不是为每个子字符串,而是仅为单独的单词。大约需要80MB(未压缩)。我担心你建议的索引的大小。。。