您可以尝试阅读大块,并避免除特定兴趣线以外的分行开销。例如,假设你没有行超过一兆字节长:
BLOCKSIZE = 1024 * 1024
def byblock_fullines(f):
tail = ''
while True:
block = f.read(BLOCKSIZE)
if not block: break
linend = block.rindex('\n')
newtail = block[linend + 1:]
block = tail + block[:linend + 1]
tail = newtail
yield block
if tail: yield tail + '\n'
这需要一个开放的文件参数,并产生约1MB保证以新行结束块。为了识别(迭代器明智)的针串的所有出现一个草垛字符串中:
def haystack_in_needle(haystack, needle):
start = 0
while True:
where = haystack.find(needle, start)
if where == -1: return
yield where
start = where + 1
要确定这样的块内的所有相关线路:
def wantlines_inblock(s, block):
last_yielded = None
for where in haystack_in_needle(block, s):
prevend = block.rfind('\n', where) # could be -1, that's OK
if prevend == last_yielded: continue # no double-yields
linend = block.find('\n', where)
if linend == -1: linend = len(block)
yield block[prevend + 1: linend]
last_yielded = prevend
这一切是如何结合在一起的:
def main():
with open('bigfile.txt') as f:
with open('smallfile.txt', 'w') as g:
for block in byblock_fulllines(f):
for line in wantlines_inblock('S0414', block)
f.write(line)
在2.7中,您可以将两个with
语句合并为一个,只是为了减少嵌套。
注意:这段代码没有经过测试,所以可能会出现(希望是小的;-)错误,例如一个一个的。性能需要调整块大小,并且必须通过对特定机器和数据进行测量来校准。你的旅费可能会改变。法律禁止的地方无效。
我认为迄今为止所有的答案都误解了你的问题。如果我明白了,你不会加速你的循环。相反,您有30,000个字符串与'S0414'相似,并且想要找到找到每个字符串的方法。这是你在找什么? – Wilduck 2010-07-14 17:19:48
我需要找到S0414和GT213以及AT3423和PR342,并且我需要找到30,000种不同的东西。我可以一次找到所有30,000,而不是让这个程序为我需要找到的每个名称都设置一行。我的计划长达30,000行,这是有问题的。 – novak 2010-07-14 18:41:48
'S0414'和'GT213'等出现在Nick这样的大文件中的同一个地方吗? http://stackoverflow.com/questions/3248395/extract-specific-text-lines/3248603#3248603 – 2010-07-14 19:32:44