2016-11-07 30 views
3

我有一本字典。字典鍵是整數,值爲對象列表有沒有像「中等」的複製品?或者:如何精確控制副本的「深度」?

我希望能夠複製的辭典,我重提確切相同的對象這樣一種方式,但不同的名單

當我使用正常的副本 - 無論是dict.copy()還是copy.copy(dict) - 我對複製字典中的列表所做的任何更改也會更改原始字典的列表。

但是,當我使用copy.deepcopy(dict)時,它會一路走來並創建新的對象,以至於我不能將例如原始字典的列表用作「待辦事項」複製的字典列表中的特定對象,或對需要與原始對象進行比較的複製字典列表進行任何其他類型的更改。

「複製」模塊(https://docs.python.org/2/library/copy.html)上的文檔似乎沒有提及任何類型的中間選項,或調整深度的某種方式。

這樣的選項或功能或不存在?如果不是,我只是從錯誤的角度思考問題?例如,我想如果我迭代字典並手動「複製」這些東西(但這似乎相當冗長!),我可能能夠實現所需的行爲。

回答

3

你可以只實現自己的 「媒介」 - 複製的版本:

import copy 


def mediumcopy(value): 
    return dict(
     (key, copy.copy(val)) 
     for key, val in value.iteritems()) 

z = {'a': [[1], [2]]} 
zcopy = mediumcopy(z) 
assert id(z) != id(zcopy) # True 
assert id(z['a']) != id(zcopy['a']) # True 
assert id(z['a'][0]) == id(zcopy['a'][0]) # True 

的Python 3版本:

def mediumcopy(value): 
    return {key: list(val) # you can still use copy.copy here 
      for key, val in value.items()} 

z = {'a': [[1], [2]]} 
zcopy = mediumcopy(z) 
assert id(z) != id(zcopy) # True 
assert id(z['a']) != id(zcopy['a']) # True 
assert id(z['a'][0]) == id(zcopy['a'][0]) # True 
+0

你打了我兩分鐘。我只是打了一個等效的迴應。 :-) – Prune

+0

@Prune :) :) :) –

+0

這很有道理!我想寫一個不同的「深度」的另一個版本(或者添加一個「if」到函數或其他東西,但實際上是相同數量的工作)? (在我的個人項目中,我只有一種「深度」,只有一個例外,所以這不是問題,但我可以想象。) – barleycorn

1

您需要創建的list S中的副本(這是價值你的dict)。即使沒有copy.copy(),也可以這樣做。

new_list = list(old_list) 

將創建old_listcopy有相同的內容,並將其存儲爲new_list

因此,您字典理解表達式來創建新的字典應爲:

new_dict = {k: list(v) for k, v in my_dict.items()} 

其中my_dict是你原來的字典。

0

您可以創建dict一個子類,實現了__deepcopy__方法淺拷貝,並使用該子類(而非本地dict)維持在想要deepcopying停止水平。

相關問題