2014-09-04 19 views
2

所以我有一個75000個元組的列表,我想推入一個字典。看起來在大約20,000個條目之後,整個程序變慢了,我認爲這是因爲字典在被填滿時被動態調整大小。初始化一個帶有未知鍵的大字典?有沒有比這更好的方法?

根據數據,字典中使用的鍵值位於元組中的不同位置,所以我不能將元組列表中的鍵從列表中提取到列表x並調用d.fromkeys(x)預先初始化大字典。我試過把一個解決方案放在一起,但在字典由ast.literal_eval評估後,我得到的是一個{'None':'None'}:/

我的溶液(不起作用) 。

d_frame = '{'+('\'None\': \'None\',' * 100000)+'}' 
    d = ast.literal_eval(d_frame) 

是否有這樣的一個內置的方法..

感謝,

編輯:我知道我的想法的愚蠢..顯然,你不能有相同的鍵在字典中....:/

只是爲了澄清,我有元組的數據像這樣的列表:

(assembly,strand,start_pos,end_pos,read_count) 
key_format : assembly_strand_val (where val = start_pos or end_pos depending on other factors) 

因爲直到我評估每個元組時我才知道密鑰,所以我不能用已知的密鑰初始化字典,所以只是想知道我是否可以創建一個空字典,然後添加它。它沒有任何意義剔除每個元組只是爲了建立一個列表,然後創建一個字典然後重複元組的評估...

編輯:我意識到瓶頸是哪裏..與每個元組,我檢查,看看相關的密鑰已退出字典,但我正在使用;

if key not in dict.keys(): 
    dict[key] = foo 

我並沒有意識到這一點,每次構建鍵的列表,並可以與經濟得多

if key not in dict: 
    dict[key] = foo 

改變這種導致速度達到了驚人的增長所取代....

+0

如果你有10萬項這些都是完全相同的,你只會得到一個有1個條目的字典,而不是100K。那實際上是你想要的嗎? – abarnert 2014-09-04 02:07:19

+0

作爲一個方面說明,你不需要寫''\'無\'... \'無\',';只寫'''無':'無',''。 – abarnert 2014-09-04 02:09:32

+0

元組中的關鍵位置如何依賴於數據?任何示例? – 2014-09-04 02:12:18

回答

7

所以我有一個75000個元組的列表,我想推入一個字典。

只需撥打dict就行了。像這樣:

>>> list_o_tuples = [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')] 
>>> d = dict(list_o_tuples) 
>>> d 
{1: 'a', 2: 'b', 3: 'c', 4: 'd'} 

用於字典的關鍵值是取決於不是由代碼示範了在所有的數據

在元組中的不同位置你向我們展示了,但是如果你可以寫一個表達式或者一個函數來取出這個鍵,你可以在dict理解中使用它,或者在一個生成器表達式中使用它,你可以傳遞給dict函數。

例如,假設元組的第一個元素是實際關鍵元素的索引。然後你會這樣寫:

d = {tup[tup[0]]: tup for tup in list_o_tuples} 

好像身邊後20000個條目,整個程序變慢,我以爲這是因爲字典是因爲它充滿動態地調整。

這似乎不太可能。是的,這個字典是調整大小的,但是它的成倍增長,而且在大小超過20000的情況下它的速度仍然非常快。配置你的程序以查看它實際上正在放緩的位置。我的猜測是要麼你正在做一些二次工作來創建或拉出值,或者你正在生成大量的存儲空間並導致交換,這兩者都與將值插入字典中沒有任何關係。

無論如何,如果你真的想「預填充」的字典,你總是可以做到這一點:

d = dict.from_keys(range(100000)) 
for i, tup in enumerate(list_o_tuples): 
    del d[i] 
    d[list_o_tuples[0]] = list_o_tuples[1] 

那麼字典從來沒有來調整。 (很明顯,如果你的鑰匙與0-99999的整數重疊,你會想要使用不同的填充鍵,但同樣的想法會起作用。)

但我敢打賭,這對你的表現完全沒有影響。


我試圖把一個解決方案,但該字典由ast.literal_eval評估後,我得到的是一個單一的{'None': 'None'}

那是因爲你要創建一個有100K的字典同一把鑰匙的副本。你不能在字典中有重複的鍵,所以當然你最終只有一個項目。

但是,這是一個紅鯡魚。創建一個字符串來評估幾乎永遠不會是答案。你的代碼弄得一塌糊塗有效僅僅是一個較慢,內存效率較低,更難以閱讀的版本是:

d = {'None': 'None' for _ in range(100000)} 

或者,如果你喜歡:

d = dict([('None', 'None')] * 100000) 
+0

歡呼聲,爲您提供幫助。如你所知,仍然在學習基礎知識。 – user1995839 2014-09-04 02:28:01

相關問題