我已经开发了一些工作代码,但它的方法非常慢。我正在尝试使用我的字典键作为搜索字符串来搜索1000个字符串的大文本文件。
这是我的工作代码......
for root, subFolders, files in os.walk(path):
for filename in files:
if filename.endswith('.txt'):
with open(os.path.join(root, filename), 'r') as f:
print '\tProcessing file: '+filename
for line in f:
if 'KEY_FRAME details' in line:
chunk = [next(f) for x in xrange(5)]
FRAME = chunk[5].split()
FRAME = FRAME[2]
framelist.append([FRAME])
newdict = dict([(d[0], d[1:]) for d in framelist])
f.close()
with open(os.path.join(root, filename), 'r') as f:
for line in f:
if any(['FRAME = '+str(i) in line for i in newdict.keys()]):
...do more text processing based on following lines and append to frame key...
txt文件太大而无法直接读入内存,因此我对同一个文件执行两次搜索,第一次搜索是根据特定字符串标题'KEY_FRAME'收集感兴趣的帧编号,并将找到的帧放入一个列表。然后我使用帧号作为键将此列表转换为dict并关闭文件。
然后我重新打开文件并根据新的搜索字符串'FRAME ='+ str(帧编号)搜索文件中每行的'任意'字典键('帧编号') 。但是虽然该方法有效,但速度非常慢。
在初始文件读取期间,我曾想过某种搜索字符串切换,但是某些'FRAME ='+ str(帧编号)字符串出现在文件中的初始'KEY_FRAME details'字符串之前
对于上述(尽管是基本的)代码,是否有更有效的方法?
感谢阅读。
在查看建议的正则表达式解决方案后,我已将脚本的结尾更改为以下内容...
framelist.append(str(FRAME))
f.seek(0)
framed = re.compile('|'.join(framelist))
framed = framed.pattern
sentences = f
for s in sentences:
if any(('FrameNumber = '+f) in s for f in framelist):
print 'first found'
if any(('FN = '+f) in s for f in framelist):
print 'second found'
最新增加的处理速度有一些改进(每个日志3分钟),所以可以容忍,虽然我希望稍微好一点,但是我每次都要搜索超过6000帧数。
答案 0 :(得分:0)
您可以采取一些措施来提高速度。
1)不要关闭&重新打开文件:您可以使用f.seek(0)
2)您正在为第二个for line in f:
循环中检查的每一行重建字符串列表。你应该在循环之外做到这一点,例如
keys = ['FRAME = '+str(i) for i in newdict.keys()]
甚至
keys = ['FRAME = '+i for i in newdict.keys()]
因为我认为newdict
的密钥已经是字符串。
然后你的测试就会变成
if any(key in line for key in keys):
该测试使用的是生成器表达式而不是列表推导,因此any()
可以在找到匹配后立即挽救,这通常比构建整个列表更快 在测试它们之前的比赛。
实际上,您可以使用正则表达式改进此匹配过程,如this answer中所示。