Python 在大文件中高效地搜索许多不同的字符串
我试图找到一种快速搜索文件中字符串的方法。首先,我不是只有一个字符串可以找到。我在一个150MB的文件中找到了1900个字符串的列表。基本上,我打开一个文件,循环1900次,以找到该文件中出现的所有字符串。以下是我搜索的一些属性Python 在大文件中高效地搜索许多不同的字符串,python,performance,string-search,Python,Performance,String Search,我试图找到一种快速搜索文件中字符串的方法。首先,我不是只有一个字符串可以找到。我在一个150MB的文件中找到了1900个字符串的列表。基本上,我打开一个文件,循环1900次,以找到该文件中出现的所有字符串。以下是我搜索的一些属性 要搜索的文件大小为150mb–它是文本文件 我需要在一个文件中找到所有出现的1900个字符串。意味着我将整个文件循环1900次以搜索所有事件 这不是简单的搜索,我必须使用正则表达式来搜索字符串 在少数情况下,我需要在找到搜索字符串的位置上方和下方各有一行。所以我需要使用
#searchstrings is list of 1900 strings
file = open("mytextfile.txt", "r")
for line in file:
for i in range(len(searchstrings)):
if searchstrings[i] in line:
print(line)
file.close()
这段代码可以完成这项工作,但速度非常慢。此外,它也没有给我选择搜索字符串所在位置上方或下方的行的选项
我用来替换字符串的另一个代码如下所示。这段代码也非常慢。这里我使用正则表达式
file = open("mytextfile.txt", "r")
file_data = file.read()
#searchstrings is list of 1900 strings
#replacestrings is list of 1900 strings that needs to be replaced
for i in range(len(searchstrings)):
src_str = re.compile(searchstrings[i], re.IGNORECASE)
file_data = src_str.sub(replacestrings[i], file_data)
file.close()
我知道代码的性能也取决于计算能力,但是,我只想知道,对于给定的硬件,以最佳速度编写代码的最佳方法是什么。我还想知道如何给程序执行计时。一些观察结果
对于惯用Python,您通常需要
for string in searchstrings:
...
而不是
for i in range(len(searchstrings)):
searchstrings[i]
并且将open(filename)作为f:…
而不是open()/close()
。with
语句将自动关闭文件
当您想用正则表达式替换多个字符串中的任何一个时,您可以这样做
re.sub('|'.join(YOUR_STRINGS), replacement, text)
因为|
是“or”的正则表达式符号,而不是单独循环
为了提高性能,我可能会尝试从CPython切换到。PyPy是同一语言的另一种实现,但通常要快得多
另一方面,如果这就是你的程序应该做的所有事情,你可能想使用一个专门的工具来完成这项工作,比如Ag或RipGrep,它已经为此项工作进行了优化。如果您使用的是Python,则可能通过subprocess.run()
函数执行。一些观察结果
对于惯用Python,您通常需要
for string in searchstrings:
...
而不是
for i in range(len(searchstrings)):
searchstrings[i]
并且将open(filename)作为f:…
而不是open()/close()
。with
语句将自动关闭文件
当您想用正则表达式替换多个字符串中的任何一个时,您可以这样做
re.sub('|'.join(YOUR_STRINGS), replacement, text)
因为|
是“or”的正则表达式符号,而不是单独循环
为了提高性能,我可能会尝试从CPython切换到。PyPy是同一语言的另一种实现,但通常要快得多
另一方面,如果这就是你的程序应该做的所有事情,你可能想使用一个专门的工具来完成这项工作,比如Ag或RipGrep,它已经为此项工作进行了优化。如果您使用的是Python,则可能通过
subprocess.run()
函数执行。我喜欢Unix命令,它们有趣、快速且高效
import re, sys
map(sys.stdout.write,(string_x for string_x in sys.stdin if re.search(sys.argv[1],string_x)))
我喜欢Unix命令,它们有趣、快速、高效
import re, sys
map(sys.stdout.write,(string_x for string_x in sys.stdin if re.search(sys.argv[1],string_x)))
为了获得最佳性能,
search\u re=re.compile(“|”).join(strings),…)
应该在循环行之前执行一次。然后每行可以调用一次search\u re.sub
。@SethMMorton当然可以,但在实践中,模式是否手动编译(一次或多次)可能没有多大关系,因为它无论如何都在re
模块中。我听到人们这么说,但实际上我已经对它进行了计时,并发现这很重要。但即使不是这样,多次执行“|”.join
的成本也很重要。所以当你说re.sub(“|”).join(你的_字符串)、replacement、text)时,我必须为1900个字符串这么做?我必须连接1900个字符串?为了获得最佳性能,search\u re=re.compile(“|”).join(strings),…)
应该在循环行之前执行一次。然后每行可以调用一次search\u re.sub
。@SethMMorton当然可以,但在实践中,模式是否手动编译(一次或多次)可能没有多大关系,因为它无论如何都在re
模块中。我听到人们这么说,但实际上我已经对它进行了计时,并发现这很重要。但即使不是这样,多次执行“|”.join
的成本也很重要。所以当你说re.sub(“|”).join(你的_字符串)、replacement、text)时,我必须为1900个字符串这么做?我必须连接1900个字符串?您可以指定预期的输出格式。例如,您希望所有结果都在一个列表中,还是希望分别存储每个搜索字符串的结果?此外,您是否只需要存储某些搜索的结果,而对于其他搜索,您只需执行操作?关于计时,请参阅。您可以指定预期的输出格式。例如,您希望所有结果都在一个列表中,还是希望分别存储每个搜索字符串的结果?此外,您是否只需要存储某些搜索的结果,而对于其他搜索,您只需执行操作?关于计时,请参阅。