2015-08-14 218 views
0

假設你有字典的字典,但你想複製幾乎整個結構(除了最內層的字典的值)。下面的代碼可以做我想做的,但我肯定有一個更聰明的方式來做到這一點:複製複雜的字典結構

import sys 

def main(argv=()): 

    # original dictionary 
    data = {1:{'l1': [1,2,3], 'l2': [2,1,6]}, 2: {'t1': ("w?",2), 't2': ("h!",4)}} 

    # new values for the innermost keys 
    newd = {'l1' : 1, 'l2' : 2, 't1' : 3, 't2' : 4} 

    copy = dict.fromkeys(data.keys(), {}) 
    for k in copy.keys(): 
     copy[k] = dict.fromkeys(data[k].keys(), None) 

    for k in copy.values(): 
     for e in k.keys(): 
      k[e] = newd[e] 

    print(data) 
    print(copy) 

if __name__ == "__main__": 
    sys.exit(main()) 

所以上面打印的代碼:

{1: {'l2': [2, 1, 6], 'l1': [1, 2, 3]}, 2: {'t1': ('w?', 2), 't2': ('h!', 4)}} 
{1: {'l2': 2, 'l1': 1}, 2: {'t1': 3, 't2': 4}} 

,這是結果我想到,但上面的代碼似乎太冗長了。有一點需要注意的是,在實際的例子中,最裏面的鍵的值並不那麼簡單,但它們是numpy數組,所以我不想對整個結構進行深層拷貝,然後替換這些值。

回答

1

您可以使用(從代碼中假設的Python 3):

>>> copy = {outer_key: {inner_key: newd.get(inner_key, inner_dict[inner_key]) for inner_key in inner_dict} for outer_key,inner_dict in data.items()} 
>>> copy 
{1: {'l1': 1, 'l2': 2}, 2: {'t1': 3, 't2': 4}} 
>>> data 
{1: {'l1': [1, 2, 3], 'l2': [2, 1, 6]}, 2: {'t1': ('w?', 2), 't2': ('h!', 4)}} 

可以簡化newd.get(inner_key, inner_dict[inner_key])newd[inner_key],如果你是100%肯定,每一個按鍵都在newd。或者如果您不關心丟失不在newd中的值的問題,則返回newd.get(inner_key)

-1

使用複印功能模塊:

import copy 
data = {1:{'l1': [1,2,3], 'l2': [2,1,6]}, 2: {'t1': ("w?",2), 't2': ("h!",4)}} 
cdata = copy.deepcopy(data) 

那麼你就必須修改最後類型的字典與新值的副本。

查看複印模塊進行深淺複印。

如果你打算用手來避免填充最後一層,那麼遞歸就是這樣做的方法。

瞭解複製模塊至少如何執行它,並使用dict.copy()方法而不是使用fromkeys()構造新的字典。

使用循環來做到這一點,限制你確切數量的內置詞典。 如果你的字典有固定的形狀,然後使用循環。

+0

請閱讀我的深度複製最後的意見。 – aaragon

+0

對不起,有關numpy數組滑落的內容。但是,我仍然告訴你該怎麼做。去看看複製模塊是如何做的,然後寫出類似的算法,它會考慮你的規格。這是我的答案的精髓。另外,複製模塊非常靈活,您可以控制一些正在進行的複製,特別是在使用自己的對象時。 – Dalen

1

使用自己的代碼,你不需要任何地方調用.keys,您可以在第一個循環創建類型的字典:

def main(): 

    # original dictionary 
    data = {1:{'l1': [1,2,3], 'l2': [2,1,6]}, 2: {'t1': ("w?",2), 't2': ("h!",4)}} 

    # new values for the innermost keys 
    newd = {'l1' : 1, 'l2' : 2, 't1' : 3, 't2' : 4} 

    copy = dict.fromkeys(data, {}) 
    for k in copy: 
     copy[k] = {key:newd[key] for key in data[k]}