嵌套字典 copy() 还是 deepcopy()? [复制]
Posted
技术标签:
【中文标题】嵌套字典 copy() 还是 deepcopy()? [复制]【英文标题】:Nested dictionaries copy() or deepcopy()? [duplicate] 【发布时间】:2017-01-21 08:18:19 【问题描述】:我尝试在代码的开头存储一个字典模板,大多数函数都会使用该模板:
字典:键 = 客户端名称,值 = 字典 2 字典 2:键 = 用户名,值 = 无我填满了我们所有的客户和他们的用户。然后代码的每一部分都可以复制这个字典并产生它自己的输出。目标是每个输出都将具有相同的“基本”字典结构,就像可以修改 None 的模板一样。
对于使用此词典的每个进程,我使用以下内容:
process1dict = clientdict
# processing 1
output1dict = ... #modified version of original clientdict, the None values have been replaced by dictionaries/lists
process2dict = clientdict
# processing 2
output2dict = ... #same here but could be different
我遇到的问题是每次将客户端复制到进程中时都会更改!
我注意到由于我最初的cliendict
中的None
值,它在每个进程之后都会发生变化(当然取决于每个进程的输出)。
编辑:我找到了复制库,但 copy()
似乎对我的情况没有帮助。我将尝试 deepcopy() 但为什么 copy()
不起作用?为什么deepcopy()
会?
【问题讨论】:
是的,你需要做deepcopy -> 没有它clientdictDNT
只是指向同一个底层字典,所以当你修改clientdict
时会被修改你也可以dict(clientdict)
或@987654331 @
您应该阅读这篇文章:Facts and myths about Python names and values,作者是 SO 老将 Ned Batchelder。
如果您不使用 deepcopy(),您的新词典成员将指向嵌入在基本词典中的词典。 deepcopy() 复制被复制字典中的内容。
感谢您的文章和回答。如果我理解正确,因为我使用的是可变对象的嵌套字典,如果我执行“copy()”并且在我的进程中使用了一些“更改”函数,例如“.append()”,它将直接将更改链接到值本身(特别是这里的“无”值)。如果我想像字典模板一样使用它(就像我在这里做的那样),我认为使用“deepcopy()”会更好。我明天试试看!
【参考方案1】:
当您使用字典或列表等可变集合并执行分配时,默认情况下您不会创建该对象的副本 - 即,将某些 dict b
分配给另一个 dict a
创建从 b
到原始对象 a
的引用,这样当你改变 b
时,你也间接地改变了 a
。
查看这个基本示例:
>>> orig = "a": 1, "b": 2
>>> new = orig
>>> new["a"] = 9
>>> orig
'a': 9, 'b': 2
>>> new
'a': 9, 'b': 2
>>> new is orig
True
要解决此问题并保持new
和orig
字典分隔不相互引用的对象,请在将其分配给new
时将deepcopy 分配给orig
:
>>> import copy
>>> orig = "a": 1, "b": 2
>>> new = copy.deepcopy(orig)
>>> new["a"] = 9
>>> orig
'a': 1, 'b': 2
>>> new
'a': 9, 'b': 2
>>> new is orig
False
另外,这里是上面链接的 Python 文档的 tl;dr:
Python 中的赋值语句不会复制对象,它们会在目标和对象之间创建绑定。对于可变集合或包含可变项的集合,有时需要一个副本,以便可以更改一个副本而不更改另一个副本。
【讨论】:
在许多情况下,深度复制不是必需的,而且实际上可能是有害的。如果您有一个属于两个客户端的对象User("Somebody")
,您可能不想将它们拆分为两个等效的对象并分别对其进行变异。如果您不想要或不需要copy.deepcopy
,您可以改用dict.copy
。 orig = "a": 1, "b": 2; new = orig.copy()
在这种特殊情况下,我没有属于两个客户端的用户名对象。我现在遇到的问题是,这个“clientdict”字典被用作模板,而“None”值被用作空白字符来填充进程中字典的其余部分。当我第一次尝试在写问题的最后一分钟使用“copy()”时,我发现它不起作用,我想我现在明白了为什么感谢你们的 cmets!谢谢大家
#upvote。这很深刻;)而且很有帮助
你救了我的夜芽!谢谢 =)以上是关于嵌套字典 copy() 还是 deepcopy()? [复制]的主要内容,如果未能解决你的问题,请参考以下文章