2014-02-23 11 views
0

我對python非常陌生。在python腳本中,我需要檢查輸入字符串是否存在於集合'titles'中;我從新行加載文件'標題'中分隔的字符串。它消耗巨大的記憶。我之所以選擇儲存,是因爲稍後有if inputstring in titles:從文件內存優化設置的Python

Line # Mem usage Increment Line Contents 
================================================ 
    1 6.160 MiB 0.000 MiB @profile 
    2        def loadtitles(): 
    3 515.387 MiB 509.227 MiB  titles = open('titles').read().split() 
    4 602.555 MiB 87.168 MiB  titles = set(titles) 

Q1。有沒有其他對象類型更有效地存儲這些大數據的內存?

我可以想出的一個解決方案是如果我將文件加載爲字符串,它會消耗與文件大小完全相同的內存;這是100%最佳的內存消耗。

Line # Mem usage Increment Line Contents 
================================================ 
    1 6.160 MiB 0.000 MiB @profile 
    2        def loadtitles(): 
    3 217.363 MiB 211.203 MiB  titles = open('titles').read() 

然後我可以做if inputstring+'\n' in titles:

Q2。有更快的選擇嗎?

回答

1

您可以:

  • 使用鍵/值存儲,如果你查找大量的密鑰。
  • 逐行迭代文件並檢查鍵是否存在,如果只有幾個鍵可以查找。
+0

使用[dict](http://i.imgur.com/Ghf56HY.png)或擱置,它可以節省大約128 MiB的內存。你可以爲此提出任何改進建議? – Nexu

+0

@Nexu,什麼內存閾值會滿足你?你不能無止境地降低內存佔用,因爲你永遠不會達到滿意的結果。 –

+0

字典將爲我做(@ 500M內存)。我只是在問,是否可以用任何其他類似字典的對象以某種方式使代碼更高效。 – Nexu

1

迭代文件(逐行處理)而不是讀取文件的全部內容將減少內存消耗。 (與發生器表達式相結合):

def loadtitles(): 
    with open('titles') as f: 
     titles = {word for line in f for word in line.split()} 
+0

事實上,這使情況變得更糟。 [Screenshot](http://i.imgur.com/9HDjGkj.png) – Nexu

+0

@Nexu,'titles = set(titles)'是沒有必要的。 'title'已經是'set'對象。 ('{... for .. in ...}'是理解。) – falsetru

+0

哦,是的。 [Screenshot2](http://i.imgur.com/bOmiyjc.png)。儘管只保存1 MiB。 (蟒2.7.3) – Nexu