[英]Python - fast file search
我有一个大(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 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:
多次搜索相同的lines
。
needle
总是一个字。
“更模糊”意味着即使needle
有点错误也应该找到线条。
这条线什么都不做:
10 ** (len(t) / len(word))
你需要更好的变量名,截至目前尚不清楚“s”和“t”是什么。 单字母变量名称仅在数学和循环变量中可接受。 你正在寻找什么,或者你正在寻找什么? 现在使用的功能对我来说没有多大意义。
由于你只匹配你搜索的任何东西的第一个匹配,在某些情况下分裂是没有意义的,所以你可能最后移动分割,但这取决于你实际搜索的内容,这是不清楚的(见2)。
更新:为了真正获得最佳性能,您需要进行配置,测试,配置和测试。 但我建议这是第一次开始:
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)
该函数将搜索持久字典中的字符串,并根据您的逻辑为您提供计算。 它会比每次迭代更快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.