2017-08-12 147 views
0

我有我通過迭代,並以一定的方式附加這樣一個空的字典嵌套元組的一個長長的清單:填充嵌套的字典

dict = {} 

將充滿這樣的:

dict = {a: {b:1,5,9,2,3}, b: {c:7,4,5,6,2,4}, c: {b:3,13,2,4,2}... } 

迭代將檢查嵌套字典是否存在,如果是,則會附加值,否則,創建一個嵌套字典。我可憐的企圖看起來是這樣的:

longlist = [(1,(a,b)),(2,(b,c)), (3,(c,b)) ... ] 
dict = {} 
    for each in longlist: 
     if dict[each[1][0]][each[1][1]]: 
      dict[each[1][0]][each[1][1]].append(each[0]) 
     else: 
      dict[each[1][0]] = {} 
      dict[each[1][0]][each[1][1]] = each[0] 

請記住,這是一個簡化版本,所以我有比值A,B,C,1,2,3在我的現實世界版本的更多。

我的方法存在的問題是,迭代失敗,因爲字典是空的開始或巢的父母不存在於字典中。對我而言,這變得越來越複雜。我無法在網上找到關於如何處理嵌套字典的大量信息,所以我認爲在這裏問問應該沒問題。我需要幫助。

+0

'字典= {a:{b:1,5,9,2,3},b:{c:7,4,5,6,2,4},c:{b:3,13,2,4,2} ...]':你能否澄清一下這是如何形成的:'[(1,(a,b)),(2,(b,c)),(3,(c,b))] ''如果你可以清楚我可以幫忙解決問題, – crazyGamer

+0

看看'(1,(a,b))',迭代將創建'a:{}'和'b:{}',變成'a:{b:{}}',然後再追加1,得到'a:{b:{1}}'。例如,因爲這是如何的原因l世界版本結束,我正在處理數百個數據:/ –

+0

@JosephKim添加了進一步的改進。希望能幫助到你! –

回答

3

下面是使用collections.defaultdict

import random 
import collections 
choices = ['a', 'b', 'c', 'd', 'e', 'f'] 

longlist = [] 
for i in range(1, 101): 
    longlist.append((i, tuple(random.sample(choices, 2)))) 

print longlist 

final = collections.defaultdict(lambda: collections.defaultdict(list)) 

for value, (key1, key2) in longlist: 
    final[key1][key2].append(value) 


print final 

一般的解決方案,我會改變你的代碼的方式是首先確保存在的嵌套字典(collections.defaultdict需要照顧這對你),然後總是追加一次。

喜歡的東西

for value (key1, key2) in longlist: 
    if not your_dict.get(key1): 
     your_dict[key1] = {} 
    if not your_dict.get(key1).get(key2): 
     your_dict[key1][key2] = [] 
    your_dict[key1][key2].append(value) 

也不是線路與「每個...「這是拆包在迭代的項目。你也可以做

for value, keys in longlist: 

但由於鍵是一個迭代,以及,你可以,如果你在括號把它包起來解開它。

+0

我發現collections.defaultdict實際上是檢查現有字典的更好方法。經過一些調整,我實際上可以解釋longlist的更長版本:'longlist = [(1,(a,b,d,e,...)),(2,(b,c,a ,f,...)),(3,(c,b,a,f,...))...]' –

1

沒有研究多到你正在嘗試做的,你可以重寫你的if聲明如果不存在密鑰不引發錯誤:

if dict_.get(each[1][0], {}).get(each[1][1], None): 
    dict_[each[1][0]][each[1][1]].append(each[0]) 

dict.get是一個非常有用的功能如果給定的鍵不存在,它將返回一個默認值。

此外,它似乎你希望列表存在。在else區塊中,您是否意味着要這麼做?

dict_[each[1][0]][each[1][1]] = [each[0]] 

這將創建一個單一元素的列表,所以現在dict[...][...].append(...)將工作。

我也建議不要使用dict來命名變量。它影響了內置的課程。

進一步的改進可能包括解壓縮for循環頭部中的項目,因此您不必執行each[0],each[1]等等。你可以使用類似:

for idx, pair in longlist: 
    x, y = pair # unpack each pair now 
    ... 

全面上市:

dict_ = {} 
for idx, pair in longlist: 
    x, y = pair 
    if dict_.get(x, {}).get(y, None): 
     dict_[x][y].append(idx) 

    else: 
     dict_[x] = {y : [idx] } 

這是比以前更具有可讀性。

+1

這很好。 get函數是我正在尋找的。我已經接受了這個答案。謝謝! –

+0

@JosephKim很高興我能幫到你。乾杯! –