2017-04-11 346 views
0

我正在編寫一個搜索函數來查找字符串中所有出現的模式。我需要的輸出之一是比賽當前線上的位置。爲此,我查找換行符的所有位置,並使用匹配位置以及換行符位置來獲取行位置。我遇到的問題是獲取換行位置。因爲我經常要處理大文件,所以我需要儘可能高效。我已經嘗試了幾種不同的方法解決這個問題。第一個是:快速獲取字符串中所有換行符的位置的方法

_newline_positions = [] 
for _index, _char in enumerate(string): 
    if _char == "\n": 
     _newline_positions.append(_index) 

這是迄今爲止最慢的,花費近80%的運行時間只是爲了這部分。

接下來我嘗試了這一點,這與我實際上如何實現搜索模式相似。

_newline_positions = [] 
    while _position < len(string): 
     _position = string.find("\n", _position) 
     if _position != -1: 
      _newline_positions.append(_position) 
     else: 
      break 
     _position += 1 

它比第一次嘗試更有效率,但它只將所花時間的百分比減少了約20%,降低到60%左右。

最後我想一個解決方案,我發現使用正則表達式:

_newline_positions = [match.start() for match in re.finditer("\n", string)] 

它最短,最快捷的同時只有40%的搜索時間,但相比在搜索功能一切時,它仍然是這是最耗時的部分。

有沒有其他方法可以做得更快,或者這種類型的正則表達式解決方案對於這個問題最有效?

+1

爲什麼哦,你爲什麼要在你的變量名前放一個前導下劃線?是......你這樣做讓我生氣:) –

+0

如果你只需要在當前行的位置*,並且你正在處理文件......你爲什麼要在整個文件中執行搜索,在內存中一次,而不是隻是迭代線和搜索每一行? – user2357112

+2

如果您可以爲此編寫一個C擴展(或者甚至可能只是使用cython),那麼相當於第一個解決方案的速度將是最快的,與Python相當的速度相比,我預計其速度會提高20到100倍。 –

回答

1

這都在大約快兩倍,在我的測試中的正則表達式:

with open(file) as f: 
    newline_positions = [-1] 
    for v in f: 
    newline_positions.append(newline_positions[-1]+len(v)) 
    print(newline_positions[1:]) 

它確實需要一個迭代過在你的文件中的所有行,這可能會或可能不會對你有用。

+0

我試過這個,但是在我的情況下它慢了大約2倍。也許我需要改變我一直在使用的分析方法... –

+0

經過多一點工作後,我發現儘管您提供的方法沒有顯示得更快,但它爲我提供了足夠的信息來移除我的大部分代碼,將我的複雜搜索變成一個非常簡單的雙循環解決方案總的來說,與舊的解決方案相比,我的大文件增加了5倍。 –

+0

這可能是我的測試方法,需要改變。小文件中的小樣本量。 – AShelly

相關問題