我有非常大的文本文件(大约150万行或更多行)来解析一些信息。我每行都会检查某些关键字(我称之为" flags")。
但是,我为每一行运行了数十项检查,因此我的程序需要相当长的时间才能完成。有没有更快的方式来检查我目前的情况?以下只是我正在做的一个例子:
nameFound = false
ageFound = false
for line in file:
if not nameFound and line.find('name:') != -1:
do something
elif not ageFound and line.find('age:') != -1:
do something
elif line.find('test pass') != -1:
do something
elif line.find('test fail') != -1:
do something
and so on ...
一些"标志"只出现一次(虽然我不知道文件中的位置或顺序),所以我使用"找到"变量用于短路检查那些"标志"。其他信息出现了数千次,所以我不能使用"发现"在我的条件下变量。 我知道的一件事是每一行,如果它包含一个"标志",最多只有一个标志。考虑到这些信息,是否有更有效的方法走吧?
答案 0 :(得分:2)
只是一个建议:您可以使用"标记"的列表,并迭代它们。
flags = [('name:', nameMethod), ('age:', ageMethod), ('test pass', tpMethod), ('test fail', tfMethod), ... ] #methods are functions without ()
for line in lines:
for flag, func in flags:
if line.find(flag) != -1:
func(args) #your args
break #same functionality as elif
顺便说一句,使用in
运算符优于str.find
或str.index
。所以if flag in line: #do something
。
这只是为了提高可读性。你绝对应该进行分析以找出瓶颈,然后看看应该/不应该修复什么。我做确定使用in
代替str.find
效率更高(我的测试估算值约为3倍)。
答案 1 :(得分:2)
在Python中,你无法做很多事情来加快速度。你一行一行,只读一次文件。你已经做了足够的事情来挤压"短路时更快地摆脱循环。代码运行所需的时间与文件大小成正比。
首先使用更快的工具过滤文件的行可能会更好。例如,mine
Unix命令通常在C中实现,并且速度非常快(比在Python中实现循环要快得多)。因此,您可以使用这样的命令(在Linux或Unix上)过滤行,然后在过滤后的文件上运行程序:
categories
另一种选择可能是使用Cython来尝试通过将代码编译为C来加速代码。但实际上,这不会让你 获得更多。
答案 2 :(得分:0)
考虑一下:每个if
在整个行中搜索(可能不存在的)标记。
假设你的线路是“爸爸已到达机场”,而你的旗帜列表是[' M','妈妈']那么很明显如果找不到M,妈妈也不会被发现。
如果您愿意付出努力来实施它们,Aho-Corasick或Rabin-Karp算法将提供显着的加速。
答案 3 :(得分:0)
正则表达式搜索可能更快:
import re
flags = "name|age|etc"
for line in file:
m = re.match(flags, line)
if m.group():
do_something(m)
或者,您可以将所有测试放在while循环中,以便在找到标志后立即退出:
flags = ['name', 'age', 'foo']
for line in file:
i = 0
while i < len(flags):
if (line.find(flags[i])):
do_something(flags[i])
i = len(flag[i])
i += 1
如果您需要为每个标志执行不同的操作,可以将该逻辑放在方法中。