2014-01-17 26 views
1

我還有很長(500K +行)兩列的表格,看起來像這樣:可以有許多創建(播種)大型辭書有效地在Python

Name Code 
1234 A 
1234 B 
1456 C 
4556 A 
4556 B 
4556 C 
... 

所以有一個元素(一個名稱)的代碼。但是不是每個代碼一行,我想列出每個元素出現的所有代碼。我想要的是這樣一本字典:

{"1234":["A","B"],"1456":["C"],"4556":["A","B","C"] ...]} 

我試過的是這(我不包括文件閱讀語法)。


    codelist = {} 
    for row in rows: 
     name,code = well.split() 
     if name in codelist.keys(): 
      codelist[name].append(code) 
     else: 
      codelist[name] = [code] 

這會創建正確的輸出,但進度變得非常慢。所以我試着用鑰匙啓動我的字典:

allnames = [.... list of all the names ...] 
codelist = dict.fromkeys(allnames) 

for row in rows: 

    name,code = well.split() 
    if codelist[name]: 
     codelist[name].append(code) 
    else: 
     codelist[name] = [code] 

這是顯着更快,我的問題是爲什麼?這個程序每次都不需要搜索字典中的所有鍵嗎?有沒有另一種方法來加快字典搜索,不包括遍歷樹?

有趣的是,我得到的錯誤,當我用同樣的條件檢查之前(如果名字codelist.keys():)吸我的字典了。

Traceback (most recent call last): 
    File .... 
    codelist[name].append(code) 
AttributeError: 'NoneType' object has no attribute 'append' 

現在,有一個關鍵,但沒有列表追加到。所以我使用codelist[name]這也是<NoneType>,似乎工作。 mydict["primed key"]<NoneType>是什麼意思? enter code here

+0

@AC,對不起 - 從IDLE剪切/粘貼...應該是{}。我編輯了這篇文章。 – Arne

回答

5

前者是慢,因爲.keys()必須先在內存中創建的所有鍵的列表,然後in操作執行對它進行搜索。所以,它是從文本文件中搜索每行的O(N),因此速度很慢。

另外一個簡單的key in dict搜索需要O(1)時間。

dict.fromkeys(allnames)

通過dict.fromkeys分配的缺省值是None,所以你不能用它append

>>> d = dict.fromkeys('abc') 
>>> d 
{'a': None, 'c': None, 'b': None} 

更好的解決方案將是在這裏使用collections.defaultdict,如果這不是一個選項,然後使用正常的dict有兩種簡單的if-else檢查或dict.setdefault


在Python3 .keys()返回一個視圖對象,所以時間複雜度可能會有所不同在那裏。但是,它仍然會比正常的key in dict搜索稍慢。

1

你可能想看看defaultdict容器,以避免檢查

from collections import defaultdict 

allnames [.... list of all the names ...] 
codelist = defaultdict(list) 

for row in rows: 

    name,code = well.split() 
    codelist[name].append(code)