[英]Python: efficiently checking a file line by line
我有非常大的文本文件(大約150萬行或更多)可以解析以獲取某些信息。 我所做的每一行都會檢查某些關鍵字(我稱它們為“標志”)。
但是,我為每一行運行許多檢查,因此我的程序需要花費大量時間才能完成。 有沒有一種更快的方式來檢查我目前的情況? 下面只是我在做什么的一個例子:
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 ...
一些“標志”僅出現一次(盡管我不知道文件中的位置或順序),因此我使用“ found”變量來縮短對那些“標志”的檢查。 其他信息出現了數千次,因此我無法在自己的條件下使用“找到的”變量。 我知道的一件事是,如果每一行包含一個“標志”,則最多只會有一個標志。 考慮到這些信息,是否有更有效的方法來解決此問題?
只是一個建議:您可以使用“標志”列表,並對其進行遍歷。
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倍)。
在Python中,您無法做很多事情來加快速度。 您將逐行執行,僅讀取一次文件。 您已經做了很多工作,可以通過短路將“速度”從循環中“擠出”出去。 代碼運行所需的時間與文件的大小成正比。
您最好先使用較快的工具過濾文件行。 例如, grep
Unix命令通常以C語言實現,並且速度非常快(比在Python中實現循環要快得多)。 因此,您可以使用以下命令(在Linux或Unix上)過濾行,然后在過濾后的文件上運行程序:
grep "flag1\|flag2\|flag3" big.txt > filtered.txt
另一種選擇可能是使用Cython嘗試通過將其編譯為C來加快代碼的速度。但是實際上,這樣做不會帶來太多好處。
考慮一下: if
每一個都在整行中搜索(可能不存在)標志。
假設您的行是“爸爸已經到達機場”,並且您的標志列表是['M','Mommy'],那么很顯然,如果找不到M,也將不會找到Mommy。
如果您願意為實現它們而付出努力,則Aho-Corasick或Rabin-Karp算法將大大提高速度。
正則表達式搜索可能會更快:
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
如果需要對每個標志執行不同的操作,則可以將該邏輯放入方法中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.