如果某个键具有列表值,则使用深层复制和浅层复制会产生一些差异

时间:2017-03-26 11:41:42

标签: python dictionary

考虑以下

from copy import deepcopy
c = {'username': 'admin', 'machines': ['foo', 'bar', 'baz']}
dc = c.copy()
d = deepcopy(dc)
d['username'] = 'mln'
d['machines'].remove('bar')
print d
print c 

结果如下:

{'username': 'mln', 'machines': ['foo', 'baz']}
{'username': 'admin', 'machines': ['foo', 'bar', 'baz']}

但使用浅拷贝时,情况会有所不同。

a = {'username': 'admin', 'machines': ['foo', 'bar', 'baz']}
b = a.copy()
b['username']='mln'
b['machines'].remove('bar')
print b
print a

结果如下:

{'username': 'mln', 'machines': ['foo', 'baz']}
{'username': 'admin', 'machines': ['foo', 'baz']}
  1. 因此,对于dict "machines"中的键d,当使用深层复制时,Python将创建一个新的列表对象,该对象与dict c中的列表对象不同。

  2. 但是当使用浅拷贝时,只有一个列表对象,两个字典都指向它。

  3. 更重要的是,当我使用浅拷贝时,对于像tuple和str这样的对象,它会创建一个新对象。

  4. 但是对于字典和列表,它只是添加了另一个引用。使用深层复制时,都会创建一个新对象。

  5. 我是对的吗?

1 个答案:

答案 0 :(得分:0)

来自文档:

  

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

     

1.浅拷贝构造一个新的复合对象,然后(尽可能)将对它的引用插入到   原来。

     

2.深拷贝构造一个新的复合对象,然后递归地将原件中的对象的副本插入其中。

所以..

  1. 否 当您使用浅拷贝时,对于字符串和元组,它不会创建新对象。 例如:
  2. >>> s1 = "string1"
    >>> s2 = copy.copy(s1)
    >>> id(s2) == id(s1)
    True
    >>> id(s2[0]) == id(s1[0])
    True
    

    两者都指向同一个对象..!

    1. 是的,如果我们使用深层复制,则会为字典和列表创建新对象,因为它们是复合对象。
    2. 查看此链接以获取更多信息: What exactly is the difference between shallow copy, deepcopy and normal assignment operation?