2013-02-23 110 views
2

我正在編寫一個程序,它工作正常,但是當它將數據庫(100MB文本文件)加載到列表時,它的內存使用量變爲700-800MB如何減少python中的大型列表使用的內存

代碼用於加載該文件的列表:

從db.hdb
database = [] 
db = open('database/db.hdb') 
dbcontent = db.read() 
for line in dbcontent.split('\n'): 
    line = line.split(':') 
    database.append(line) 

Snipplet:

14200:917cb8a3d1d9eb24af6c5bcf3bf7e401:Trojan.Downloader-1420 
7168:a105e2cc8148158cd048360eb847c7d0:Trojan.Downloader-1421 
7168:c61ef67b5e7eef19ef732f55116742f6:Trojan.Downloader-1422 
7168:851b6320148122104f50445ea2684c9f:Trojan.Downloader-1423 
7168:ca128383c79a56d930eb4a7ff5026e31:Trojan.Downloader-1424 
355204:4af89f8d219f94462cf2f8cb8eb4c6d7:Trojan.Bancos-2053 
356984:2bfb53d76891059b79122e13d1537e4a:Trojan.Bancos-2054 
363520:edbbdf497cda1ba79c06ea40673d963e:Trojan.Bancos-2055 
367616:d85f719b032dbf39800d90ca881fd225:Trojan.Bancos-2056 
370688:6cb572fd2452416dc4ea09e3ad917e66:Trojan.Bancos-2057 
370688:ef34885677230061649d30ea66d7b0a1:Trojan.Bancos-2058 
399360:8578b664706cfdc2f653680bac1b1b6e:Trojan.Bancos-2059 
401408:de62af250b5a3e1ba1e9c517629383dd:Trojan.Bancos-2060 
622592:8a236340c0a8c76343f6fb581314fadf:Trojan.Bancos-2061 
622592:29f3499488ba1814c62fac3c2f3bda54:Trojan.Bancos-2062 
622592:5d023bccf2ff097ccbc0ab0eab4a6ee7:Trojan.Bancos-2063 
622592:3d6a25ed1f0e2001e72812ce1adf37d3:Trojan.Bancos-2064 
622592:eaff242b601807e5805c189752d39124:Trojan.Bancos-2065 
623104:8cd8e788d33cf40412d3346a525e4cce:Trojan.Bancos-2066 
625152:25470d6895cb0e5c2e7181cb9a201ae0:Trojan.Bancos-2067 
625152:436d574cef37b2e62d9b801b8fc2c4f1:Trojan.Bancos-2068 
647168:51eb4e43f24cf511e6715cc8667babcd:Trojan.Bancos-2069 

(完整文件具有〜1800000線)

如何減少內存使用

+1

這取決於你要用這些數據做什麼。你可能只是簡單地加載一塊。或者購買更多的內存。 :)現在800MB不再是一個問題。 – freakish 2013-02-23 13:10:05

+0

除非我有一個樹莓pi具有512MB RAM,並且不可升級:(在我的Windows PC上沒有問題,但是在樹莓派上它是 – Yannick 2013-02-23 13:17:16

+0

另外,我看不到如何用您的databse是一個列表:在列表中搜索任何東西都是線性的 - 也就是說,如果你必須檢查給定的簽名是否在你的數據庫中,你必須逐個檢查所有的項目,你應該至少使用一個字典並使用簽名字段作爲密鑰 – jsbueno 2013-02-23 16:42:37

回答

2

你應該使用文件對象作爲迭代器來減少文件的內存使用量。然後你可以處理數據庫列表而不是全部。例如:

results = [] 
database = [] 
for line in open("database/db.hdb"): 
    line = line.split(':') 
    #You could then manage database in chunks? 
    database.append(line) 
    if len(database) > MAX: 
     #dosomething with database list so far to get result 
     results.append(process_database(database)) 
     database = [] 
#do something now with individual results to make one result 
combine_results(results) 
+0

謝謝!這減少了300MB使用的內存:D – Yannick 2013-02-23 13:33:54

-1

只要你不需要在內存中完整的文件,你可以一次讀取一行:

database = [] 
db = open('database/db.hdb') 
line = db.readline() 
while line: 
    line = line.split(':') 
    database.append(line) 
    line = db.readline() 

See here for details on file.readline()

+0

這不會做你認爲它的做法,'readline()'會將下一行作爲一個字符串返回,所以你的for循環會迭代該行中的字符 – 2013-02-23 13:50:27

+0

感謝您的反饋。修復了代碼循環。 – TAS 2013-02-23 14:43:20

+0

Python中的文件對象是作爲'for'循環中的迭代器使用的 - 請參閱批准的答案。 – jsbueno 2013-02-23 16:46:05