2012-06-27 72 views
1

對不起另一個新手查詢:建立在這裏給出的建議, optimizing以特定格式(Python)書寫和閱讀字典

我需要能夠逐步建立一個字典,即一個鍵:一次在一個for循環內的值:值。具體而言,該詞典會看起來像(N鍵,其中每個值是一個列表的列表的較小的內列表具有3個元素):

dic_score ={key1:[ [,,], [,,], [,,] ...[,,] ], key2:[ [,,], [,,], [,,] ..[,,] ] ..keyN:[[,,], [,,], [,,] ..[,,]]} 

正在從以下範例生成此DIC,一個嵌套循環。

for Gnodes in G.nodes()  # Gnodes iterates over 10000 values 
    Gvalue = someoperation(Gnodes) 
    for Hnodes in H.nodes() # Hnodes iterates over 10000 values 
     Hvalue =someoperation(Hnodes) 
     score = SomeOperation on (Gvalue,Hvalue) 
     dic_score.setdefault(Gnodes,[]).append([Hnodes, score, -1 ]) 

然後我需要把這些列表進行排序,但在這裏給出的答案,optimizing(取代內部循環使用發電機表達的是一個選項)
[注意DIC將包含10000每個鍵與10000個小元素的列表相關聯]

由於循環計數器很大,生成的字典非常龐大,而且內存不足。

我怎麼能寫寫的關鍵,一旦價值(名單列表),因爲它是生成一個文件,這樣我就不需要保存整個詞典在內存中。然後,我希望能夠讀取以相同的格式返回字典,即類似於dic_score_after_reading [key]的字典,向我返回我正在查找的列表的列表。

我在做這個寫作和每個關鍵字的閱讀跳躍:價值將大大緩解內存需求。有沒有更好的數據結構來做到這一點?我應該考慮一個數據庫,可能像Buzhug,這將使我能夠靈活地訪問和遍歷與每個鍵相關的列表嗎?

我目前使用cPickle來轉儲整個字典,然後通過load()讀取它,但cPickle在一次性轉儲如此大的數據時崩潰。

道歉,但我不知道做這種類型的東西的最佳做法。謝謝 !

回答

1

您可以使用ZODB與包含的BTrees實施結合使用。

給出的是一個映射類結構,它將單獨的條目分別寫入對象存儲區。您需要使用savepoints或普通transactions將數據刷新到存儲,但您可以通過這種方式處理大量數據。

+0

感謝您的快速響應!讓我深入瞭解這一點,因爲我不知道這些如何工作。 –

+0

@Martjin:按照你的建議,我嘗試將ZODB與Btree結合使用,但我遇到了一個小問題。當我打開數據庫閱讀時,我發現有些記錄丟失。具體來說,如上所述,我存儲我的dic。以Btree的形式並將其附加到根。 Btree包含20個鍵,每個鍵對應列表(與原始問題相同)。但是,當我關閉一次後再打開數據庫時,某些列表元素會丟失。我每次追加密鑰後都使用transaction.commit()。 –

+0

在內部循環中,每次迭代後,我都會執行btree.setdefault(key,[])。append([ref_node,score,-1]); transaction.commit(),以便與每個密鑰構建關聯的列表逐步增加。當我完成後,我會看到完整列表,但是當我重新打開時,我在列表中找到缺少的元素[請參閱原始文章]。任何關於可能出錯的想法/建議?提前致謝 ! –