我有一个包含元组的列表字典。我想创建一个字典副本,只编辑其中一个副本。以下是复制通常适合我的字典的四种方法:
import copy
dicta = {'A':[(1,1)]}
dictb = dicta.copy()
dictc = dict(dicta)
dictd = dict((k,v) for k,v in dicta.items())
dicte = copy.deepcopy(dicta)
如果你试图改变口述:
dicta['A'][0] = [(9,9)]
除了通过copy.deepcopy
创建的副本外,您会发现每个副本仍然指向与dicta相同的字典。尽管dicta is dictX
为所有副本返回False
,但仍会发生这种情况。
这里发生了什么?
答案 0 :(得分:3)
dictb
到dictd
是dicta
的“浅层副本”。这意味着它们确实是新的词典(这就是为什么它们与dicta
不同),但它们的内容是同一个对象。看这里:
>>> dicta is dictb
False
>>> dicta['A'] is dictb['A']
True
>>> dicta['A'] is dicte['A']
False
只有deepcopy命令进入,并以递归方式复制它复制的内容的内容。
答案 1 :(得分:1)
只有copy.deepcopy()
递归复制字典,这就是为什么只有它起作用。其他方法不会递归遍历所有字典并保持链接到所有相同的列表(或存储在字典中的任何对象),但它们仍然返回不同的字典(这就是dicta is dictX
返回{{1}的原因所有副本)。例如。您可以尝试删除副本中的某些条目,相应的条目不会被删除。
答案 2 :(得分:1)
您刚刚复制了字典,但没有复制其中的内容。所以你确实创建了一个新的字典,但它指向了同一个列表。
答案 3 :(得分:0)
如果您尝试dicta == dictX
,除了通过true
copy.deepcopy
因为is
检查两个变量是否指向同一个对象。在创建副本时,他们指向不同的字典。
检查
>>>id(dicta)
>>>id(dictb)
>>>id(dicta['A'])
>>>id(dictb['A'])
这将清除你的怀疑。