我设置了dict2 = dict1。当我编辑dict2时,原来的dict1也改变了。为什么?

>>> dict1 = {"key1": "value1", "key2": "value2"}
>>> dict2 = dict1
>>> dict2["key2"] = "WHY?!"
>>> dict1
{'key2': 'WHY?!', 'key1': 'value1'}

当前回答

对于嵌套的字典,不要使用dict(srcData)或srcData.copy()或{**srcData},因为如果你改变了秒级或更多,它也会修改源字典

srcData = {
  'first': {
    'second': 'second Value'
  }
}
newData = dict(srcData) # srcData.copy() or {**srcData}
newData['first']['second'] = 'new Second Value'

print(srcData)
print(newData)

# it will print
# srcData: {'first': {'second': 'new Second Value'}}
# newData:{'first': {'second': 'new Second Value'}}

# but it should be
# srcData: {'first': {'second': 'second Value'}}
# newData:{'first': {'second': 'new Second Value'}}

deepcopy的另一个选择是使用json技巧,如Javascript json .parse(json .stringify(obj))

import json

srcData = {'first': {'second': 'second Value'}}
newData = json.loads(json.dumps(srcData))
newData['first']['second'] = 'new Second Value'

print(srcData)
print(newData)

# srcData: {'first': {'second': 'second Value'}}
# newData: {'first': {'second': 'new Second Value'}}

其他回答

你也可以用字典理解来创建一个新字典。这避免了导入副本。

dout = dict((k,v) for k,v in mydict.items())

当然,在python >= 2.7中,你可以这样做:

dout = {k:v for k,v in mydict.items()}

但对于向后比较。,上面的方法更好。

Dict2 = dict1不复制字典。它只是为程序员提供了另一种方法(dict2)来引用同一个字典。

python中的每个变量(比如dict1或str或__builtins__)都是指向机器内部某个隐藏的柏拉图式“对象”的指针。

如果您设置dict1 = dict2,您只需将dict1指向与dict2相同的对象(或内存位置,或任何您喜欢的类比)。现在,dict1引用的对象就是dict2引用的对象。

你可以检查:dict1是dict2应该是True。另外,id(dict1)应该与id(dict2)相同。

你需要dict1 = copy(dict2),或者dict1 = deepcopy(dict2)。

复制和深度复制的区别是什么?Deepcopy将确保dict2的元素(你是否将它指向一个列表?)也是副本。

我不怎么使用深度复制——编写需要它的代码通常是一种糟糕的实践(在我看来)。

在python 3.5+上,有一种更简单的方法来实现浅拷贝,即使用** unpackaging操作符。由Pep 448定义。

>>>dict1 = {"key1": "value1", "key2": "value2"}
>>>dict2 = {**dict1}
>>>print(dict2)
{'key1': 'value1', 'key2': 'value2'}
>>>dict2["key2"] = "WHY?!"
>>>print(dict1)
{'key1': 'value1', 'key2': 'value2'}
>>>print(dict2)
{'key1': 'value1', 'key2': 'WHY?!'}

**将字典解包到一个新字典中,然后分配给dict2。

我们还可以确认每个字典都有一个不同的id。

>>>id(dict1)
 178192816

>>>id(dict2)
 178192600

如果需要深度复制,那么copy.deepcopy()仍然是可行的方法。

Python中的赋值语句不复制对象,而是在目标和对象之间创建绑定。

因此,dict2 = dict1,结果在dict2和dict1引用的对象之间产生另一个绑定。

如果你想复制字典,你可以使用copy模块。 复制模块有两个接口:

copy.copy(x)
Return a shallow copy of x.

copy.deepcopy(x)
Return a deep copy of x.

浅复制和深复制之间的区别只与复合对象(包含其他对象的对象,如列表或类实例)相关:

浅拷贝构造一个新的复合对象,然后(在可能的范围内)将对原始对象的引用插入其中。

深度复制构造一个新的复合对象,然后递归地将原始对象中的对象的副本插入其中。

例如,在python 2.7.9中:

>>> import copy
>>> a = [1,2,3,4,['a', 'b']]
>>> b = a
>>> c = copy.copy(a)
>>> d = copy.deepcopy(a)
>>> a.append(5)
>>> a[4].append('c')

结果是:

>>> a
[1, 2, 3, 4, ['a', 'b', 'c'], 5]
>>> b
[1, 2, 3, 4, ['a', 'b', 'c'], 5]
>>> c
[1, 2, 3, 4, ['a', 'b', 'c']]
>>> d
[1, 2, 3, 4, ['a', 'b']]