使用int和str时

时间:2017-03-10 09:18:58

标签: python shallow-copy

关于副本的Python文档

  

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

     

浅复制构造一个新的复合对象,然后(尽可能)将对它的引用插入到原始对象中找到的对象。   深拷贝构造一个新的复合对象,然后递归地将副本插入到原始对象中找到的对象。

我认为浅拷贝应该复制列表的引用,所以更新shallow_copy_list也应该改变原始列表,但是第一个例子没有按预期工作。

Python 3.6.0(默认,2016年12月24日,08:01:42)darwin上的[GCC 4.2.1兼容的Apple LLVM 8.0.0(clang-800.0.42.1)]

items = [1, 2, 3, 4, 5, 6]
items_copy = items[:]
items_copy[0] = 'a'
items_copy == items
False

我认为这是一个浅层副本,而items_copy == items应返回True,但它是假的。 但另一个例子返回True

items = [{'id': 1, 'name': 'laptop', 'value': 1000}, {'id': 2, 'name': 'chair', 'value': 300},]
items_copy = items[:]
items_copy[0]['id'] = 'a'
items_copy == items
True

参考文献:

Python Shallow and deep copies

Ned Batchelder - Facts and Myths about Python names and values - PyCon 2015

2 个答案:

答案 0 :(得分:0)

据我所知:浅层复制表示字典内容为not copied by value,但创建新参考。

看看这个例子。

items = [{'id': 1, 'name': 'laptop', 'value': 1000}, {'id': 2, 'name': 'chair', 'value': 300},]
items_copy = items[:]
items_copy[0]['id'] = 'a'

print items_copy,id(items_copy),items,id(items)
print items_copy == items

输出:

[{'id': 'a', 'value': 1000, 'name': 'laptop'}, {'id': 2, 'value': 300, 'name': 'chair'}] 4455943200 [{'id': 'a', 'value': 1000, 'name': 'laptop'}, {'id': 2, 'value': 300, 'name': 'chair'}] 4455866312
True
items = [{'id': 1, 'name': 'laptop', 'value': 1000}, {'id': 2, 'name': 'chair', 'value': 300},]
items_copy = items[:]
items_copy[0]= 'a'
print items_copy,id(items_copy),items,id(items)
print items_copy == items

输出:

['a', {'id': 2, 'value': 300, 'name': 'chair'}] 4455943200 [{'id': 'a', 'value': 1000, 'name': 'laptop'}, {'id': 2, 'value': 300, 'name': 'chair'}] 4455866312
False

答案 1 :(得分:0)

此代码:

items_copy[0] = 'a'

表示"将items_copy[0]中的项目替换为a。它更改items_copy引用的对象(因此更改引用该对象的所有其他变量,在这种情况下包括items),但没有效果以前在items_copy[0]中的项目(在这本字典中)。

这类似于以下事件序列:

foo = {'id': 1, 'name': 'laptop', 'value': 1000}
bar = foo
foo = 'a'
foo == bar

这将返回False,因为bar仍然是(未更改的)字典对象。

在第二种情况下,您没有修改任何一个列表,但是您确实修改了两个副本引用的(第一个)字典,类似于此序列:

foo = {'id': 1, 'name': 'laptop', 'value': 1000}
bar = foo
foo['id'] = 'a'
foo == bar

这将返回True。 (这与您的第二个示例略有不同,因为在这种情况下foobar不仅相等,而且实际上引用同一个对象。)