簡體   English   中英

Python:高效地逐行檢查文件

[英]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.findstr.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-CorasickRabin-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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM