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

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

当前回答

虽然dict.copy()和dict(dict1)会生成一个副本,但它们只是浅副本。如果你想要一个深度拷贝,copy.deepcopy(dict1)是必需的。一个例子:

>>> source = {'a': 1, 'b': {'m': 4, 'n': 5, 'o': 6}, 'c': 3}
>>> copy1 = source.copy()
>>> copy2 = dict(source)
>>> import copy
>>> copy3 = copy.deepcopy(source)
>>> source['a'] = 10  # a change to first-level properties won't affect copies
>>> source
{'a': 10, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> copy1
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> copy2
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> copy3
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> source['b']['m'] = 40  # a change to deep properties WILL affect shallow copies 'b.m' property
>>> source
{'a': 10, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}}
>>> copy1
{'a': 1, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}}
>>> copy2
{'a': 1, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}}
>>> copy3  # Deep copy's 'b.m' property is unaffected
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}

关于浅拷贝和深拷贝,请参阅Python复制模块docs:

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

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

其他回答

Python从不隐式复制对象。当您设置dict2 = dict1时,您将使它们引用相同的dict对象,因此当您更改它时,对它的所有引用都将引用处于当前状态的对象。

如果您想复制字典(这是罕见的),您必须显式地使用

dict2 = dict(dict1)

or

dict2 = dict1.copy()

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

>>> dict2 = dict1
# dict2 is bind to the same Dict object which binds to dict1, so if you modify dict2, you will modify the dict1

复制Dict对象有很多方法,我简单用一下

dict_1 = {
           'a':1,
           'b':2
         }
dict_2 = {}
dict_2.update(dict_1)

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 2.7和3中创建字典副本的最佳和最简单的方法是…

创建一个简单(单层)字典的副本:

1. 使用dict()方法,而不是生成指向现有dict的引用。

my_dict1 = dict()
my_dict1["message"] = "Hello Python"
print(my_dict1)  # {'message':'Hello Python'}

my_dict2 = dict(my_dict1)
print(my_dict2)  # {'message':'Hello Python'}

# Made changes in my_dict1 
my_dict1["name"] = "Emrit"
print(my_dict1)  # {'message':'Hello Python', 'name' : 'Emrit'}
print(my_dict2)  # {'message':'Hello Python'}

2. 使用python字典内置的update()方法。

my_dict2 = dict()
my_dict2.update(my_dict1)
print(my_dict2)  # {'message':'Hello Python'}

# Made changes in my_dict1 
my_dict1["name"] = "Emrit"
print(my_dict1)  # {'message':'Hello Python', 'name' : 'Emrit'}
print(my_dict2)  # {'message':'Hello Python'}

创建一个嵌套的或复杂的字典的副本:

使用内置的复制模块,它提供了通用的浅拷贝和深拷贝操作。此模块在Python 2.7和3中都有

import copy

my_dict2 = copy.deepcopy(my_dict1)