2012-03-25 174 views
11

我有一個巨大的文件(大約有200k個輸入)。輸入的格式爲:在Python中創建一個包含列表的字典

A B C D 
B E F 
C A B D 
D 

我讀這個文件,並將其在列表存儲如下:

text = f.read().split('\n') 

這種分裂,只要自己認爲一個新行的文件。因此,文本如下所示:

[[A B C D] [B E F] [C A B D] [D]] 

我必須現在將這些值存儲在字典中,其中鍵值是每個列表中的第一個元素。即密鑰將是A,B,C,D。 我發現很難輸入值作爲列表的其餘元素。即字典應該是這樣的:

{A: [B C D]; B: [E F]; C: [A B D]; D: []} 

我也做了以下內容:

inlinkDict = {} 
    for doc in text: 
    adoc= doc.split(' ') 
    docid = adoc[0] 
    inlinkDict[docid] = inlinkDict.get(docid,0) + {I do not understand what to put in here} 

請幫幫忙,我怎麼應該值添加到我的字典。如果列表中沒有元素,那麼它應該是0,除了那些將是關鍵值的元素。就像例如在0

+0

你想要的字典中'{A:[B,C,D]; B:[E,F]; C:[A,B,D]; D:[]}'?或者也許'{A:「B C D」; B:「E F」; C:「A B D」; D:0}'? – huon 2012-03-25 05:27:38

+0

請編輯你的問題,說出你想要做的重複鍵;例如,如果你有第5行包含'A P Q R'?你想如何將B C D ...的值存儲爲列表'['B','C','D']'?如果將空列表的情況表示爲空列表[[]',而不是整數「0」)會更好。 – 2012-03-25 05:34:13

+0

@JohnMachin:沒有重複的值。是的,將值存儲爲列表肯定會有所幫助。我將編輯我的問題。 – Nerd 2012-03-25 05:38:56

回答

17

嘗試使用切片:

inlinkDict[docid] = adoc[1:] 

這會給你一個空列表,而不是對其中只有鍵值爲上線的情況下0。爲了得到一個0,而不是你可以使用有條件分配:

inlinkDict[docid] = adoc[1:] if adoc[1:] else 0 

更簡單的方法用字典理解:

>>> with open('/tmp/spam.txt') as f: 
... data = [line.strip().split() for line in f.readlines()] 
... 
>>> {d[0]: d[1:] for d in data} 
{'A': ['B', 'C', 'D'], 'C': ['A', 'B', 'D'], 'B': ['E', 'F'], 'D': []} 
>>> {d[0]: ' '.join(d[1:]) if d[1:] else 0 for d in data} 
{'A': 'B C D', 'C': 'A B D', 'B': 'E F', 'D': 0} 

注:字典鍵必須是唯一的,所以如果你有,比如說,以'C'開頭的兩行將被覆蓋。

+0

這將工作onli在2.7 python更好的方式是dict([(d [0],d [1:])爲d in數據]) – pod2metra 2012-03-25 07:58:13

+0

這也將讀取內存中的整個文件。 – 2012-03-25 08:25:28

18

字典解析使得這一任務的短期工作:

>>> s = [['A','B','C','D'], ['B','E','F'], ['C','A','B','D'], ['D']] 
>>> {t[0]:t[1:] for t in s} 
{'A': ['B', 'C', 'D'], 'C': ['A', 'B', 'D'], 'B': ['E', 'F'], 'D': []} 
+1

如果你使用的是沒有dict comprehensions的老版本的python,你可以使用'dict(t [0],t [1:]代替t)'而不是 – forivall 2012-03-25 05:58:09

+11

如果你使用的是版本的python在生成器表達式之前,可以使用''dict([(t [0],t [1:])'來代替。而且,如果你使用的版本比這個版本早,你可以使用''s:d [t [0]] = t [1:]''。而且,如果時間久遠,Python不存在,則可以使用Dartmouth BASIC來DIM數組,以便可以通過編寫自己的散列函數來模擬散列表。而且,如果您正在使用沒有更高級別語言的系統,則可以將您的彙編程序代碼轉換爲機器語言,然後使用切換開關輸入程序... – 2012-03-25 06:06:12

+0

Ha,ha,ha。只是2.5和2.6還是很常見的,字典的理解只能在2.7中加入。 – forivall 2012-03-25 06:10:27

4

接受的答案是正確的,只是它讀取整個文件到內存(可能不是理想的,如果你有一個大的文件),並它會覆蓋重複的密鑰。

使用defaultdict的替代方法,它可以從Python 2.4中解決了這個:

from collections import defaultdict 
d = defaultdict(list) 
with open('/tmp/spam.txt') as f: 
    for line in f: 
    parts = line.strip().split() 
    d[parts[0]] += parts[1:] 

輸入:

 
A B C D 
B E F 
C A B D 
D 
C H I J 

結果:

>>> d = defaultdict(list) 
>>> with open('/tmp/spam.txt') as f: 
... for line in f: 
...  parts = line.strip().split() 
...  d[parts[0]] += parts[1:] 
... 
>>> d['C'] 
['A', 'B', 'D', 'H', 'I', 'J'] 
相關問題