2009-08-19 379 views
16

我將約400萬個不同的密鑰放入Python字典中。 創建此字典需要大約15分鐘,並在我的機器上消耗大約4GB的內存。字典完全創建後,查詢字典很快。如何在Python中設置字典的初始大小?

我懷疑字典創建是非常耗費資源的,因爲字典經常被重新編譯(隨着它的增長)。 是否可以創建一個Python的字典與一些初始大小或桶號?

我的字典從一個數字指向一個對象。

class MyObject(object): 
    def __init__(self): 
    # some fields... 

d = {} 
d[i] = MyObject() # 4M times on different key... 
+0

非常類似於http://stackoverflow.com/questions/311775/python-create-a-list-dict-with-initial-capacity – 2009-08-19 09:13:52

+0

你能讓我們知道你的密鑰的來源/格式,所以我們可以改進an魚? – 2009-08-19 09:39:44

+0

它是一個數字的關鍵 – tkokoszka 2009-08-19 10:09:11

回答

24

由於性能問題,最好測量。這裏有一些時間:

d = {} 
for i in xrange(4000000): 
    d[i] = None 
# 722ms 

d = dict(itertools.izip(xrange(4000000), itertools.repeat(None))) 
# 634ms 

dict.fromkeys(xrange(4000000)) 
# 558ms 

s = set(xrange(4000000)) 
dict.fromkeys(s) 
# Not including set construction 353ms 

最後一個選項不做任何調整大小,它只是從集合中複製散列並增加引用。正如你所看到的,調整大小並沒有花費很多時間。這可能是你的對象創建緩慢。

+0

無論如何初始化字典,填充數據總是需要很長時間。看起來確實所有的時間都花在創建對象上。謝謝! – tkokoszka 2009-08-19 10:32:21

4

你可以嘗試從內容與dict.fromkeys類方法填充分隔密鑰散列。它將創建一個已知大小的dict,所有值默認爲None或您選擇的值。之後,您可以遍歷它來填充值。它會幫助你計算所有密鑰的實際散列。不知道你是否能夠顯着提高速度。

2

如果您DATAS需要/可以存儲在光盤上或許您可以將您的DATAS在BSDDB database或使用Cpickle加載/存儲您的dictionnary

8

我嘗試:

a = dict.fromkeys((range(4000000))) 

它創建在約3秒,4個000 000項的字典。之後,設定值非常快。所以我認爲dict.fromkey是最快的方式。

+4

+1提到dict.fromkeys()。但是,使用range()來指定鍵意味着你最終得到了順序鍵的字典。如果這是必需的,爲什麼不使用列表?a = [None] * 4000000 – 2009-08-19 09:53:23

+1

這不是直接的解決方案,只是一個演示,你可以使用鍵來預先生成字典在一個非常排序的時間。 – 2009-08-19 11:47:28

+1

符合@ShawnChin提出的觀點,如果你不希望數字1 ... 4M作爲關鍵字?或者更一般地說,如果你事先不知道你的鑰匙,但你只知道他們有幾百萬? – posdef 2016-03-10 11:29:32

1

你是否用初始化所有鍵的新「空」相同類型的實例?是不是可以寫一個defaultdict或什麼東西來創建訪問它時的對象?