Can';在使用int和str时,无法理解python浅拷贝

Can';在使用int和str时,无法理解python浅拷贝,python,shallow-copy,Python,Shallow Copy,Python文档关于复制 浅复制和深复制之间的区别仅与复合对象(包含其他对象的对象,如列表或类实例)相关: 浅复制构造一个新的复合对象,然后(尽可能)向其中插入对原始对象的引用。 深度副本构造一个新的复合对象,然后递归地将在原始副本中找到的对象的副本插入其中 我认为浅层复制应该复制列表的引用,因此更新浅层复制列表也应该更改原始列表,但是第一个示例没有按预期工作 达尔文上的Python 3.6.0(默认,2016年12月24日,08:01:42)[GCC 4.2.1兼容苹果LLVM 8.0.0(c

Python文档关于复制

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

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

我认为浅层复制应该复制列表的引用,因此更新浅层复制列表也应该更改原始列表,但是第一个示例没有按预期工作

达尔文上的Python 3.6.0(默认,2016年12月24日,08:01:42)[GCC 4.2.1兼容苹果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\u copy==items应该返回True,但它是False。 但另一个例子是正确的

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
参考资料:


据我所知:浅复制意味着字典的内容不是按值复制的,而是创建一个新的引用。

看看这个例子

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
['a', {'id': 2, 'value': 300, 'name': 'chair'}] 4455943200 [{'id': 'a', 'value': 1000, 'name': 'laptop'}, {'id': 2, 'value': 300, 'name': 'chair'}] 4455866312
False

输出:

[{'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
['a', {'id': 2, 'value': 300, 'name': 'chair'}] 4455943200 [{'id': 'a', 'value': 1000, 'name': 'laptop'}, {'id': 2, 'value': 300, 'name': 'chair'}] 4455866312
False
此代码:

items_copy[0] = 'a'
表示“用
a
替换
items\u-copy[0]
中的项目。它更改
items\u-copy
引用的对象(因此更改引用该对象的所有其他变量,在本例中不包括
items
),但对以前在
items\u-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
(这与第二个示例略有不同,因为在本例中,
foo
bar
不仅相等,而且实际上指的是同一个对象。)

整数和字符串都是不可变的-您不能修改它们,您只需分配新值来代替旧值。旧值是不变的(当然,如果它符合条件,垃圾收集器可能会删除它).我可以这样理解吗:两个副本引用相同的dict,您更改dict,因此两个副本都会更改;两个副本引用相同的int,但您不能更改int,您只需重新绑定项[0]的值,因此项[0]更改,但项\u copy不会更改。不能修改int与此无关。在Python中,不能通过指定包含该对象的变量来修改任何对象;该变量被新对象替换,而旧对象不变。因此
r=7
永远不会更改用于引用的
r
对象,以及
r[8]=7
从不更改
r[8]
用于引用的对象(当然,会更改
r
引用的对象的内容)。