今天的我更强了 发表于 2020-6-21 16:20:18

浅拷贝和深拷贝

从网上搜了一部分,但还是没理解,主要想搞明白 b拷贝的a,什么情况下一方改变两者都改变,什么时候只改变自身?
再就是赋值操作, 直接赋值,默认浅拷贝传递对象的引用而已,原始列表改变,被赋值的b也会做相同的改变 这是网上的解释,
然后我尝试 a=6 ,b=a ,然后 a=7,b却没有发生改变 还是6,这不是矛盾吗?
求大神指教

xiaosi4081 发表于 2020-6-21 16:21:13

本帖最后由 xiaosi4081 于 2020-6-21 16:34 编辑

列表才是这样的:
>>> b = ["a"]
>>> a = b
>>> a.append("t")
>>> b
['a', 't']
>>>
因为普通赋值是把1号变量存储进一个新的变量里
列表只是一个指针
所以面a只是复制了b的地址
而:
>>> c = b.copy()
>>> c.append("e")
>>> c
['a', 't', 'e']
>>> b
['a', 't']
就是把b的内容复制到c

PS:不妨去看看c语言的数组

求最佳!!{:10_254:}

Twilight6 发表于 2020-6-21 16:27:43

然后我尝试 a=6 ,b=a ,然后 a=7,b却没有发生改变 还是6,这不是矛盾吗?

你可以这样理解,把变量名当成数值的别名,你这里的赋值 a = 6 只是把 6 这个数值取了个 a 的外号

a 是指向 6 的 ,而 b = a 实际上还是为 6 取了第二个别名 b ,所以此时 6 有两个别名 a,b

当你 a=7 ,时候 就把这个别名给了 7 , 而 b 这个别名还是 6 的 ,所以就不会发生改变

Twilight6 发表于 2020-6-21 16:31:12

深拷贝需要导入copy 模块来调用
import copy
x =
y = copy.deepcopy(x)

今天的我更强了 发表于 2020-6-21 16:36:33

xiaosi4081 发表于 2020-6-21 16:21
列表才是这样的:

因为普通赋值是把1号变量存储进一个新的变量里


list1=
list2=
dict1={'1':list1,'2':list2}
dict2=dict1.copy()
dict1['1']=5
result=dict1['1']+dict2['1']
print(result)
print(dict2)

这个为什么会同时发生改变呢? 这和第二个例子不一样吗?

Stubborn 发表于 2020-6-21 16:38:34

本帖最后由 Stubborn 于 2020-6-21 16:43 编辑

理解一下,纸片(不可变类型数据),和纸盒(可变类型数据)的区别

当指针改变了指向,指向新的“纸片”‘纸盒’,才会发生具体的改变。

https://fishc.com.cn/thread-171936-1-1.html

今天的我更强了 发表于 2020-6-21 16:39:09

Twilight6 发表于 2020-6-21 16:31
深拷贝需要导入copy 模块来调用

list1=
list2=
dict1={'1':list1,'2':list2}
dict2=dict1.copy()
dict1['1']=5
result=dict1['1']+dict2['1']
print(result)
print(dict2)
和下面这串代码
>>> c = b.copy()
>>> c.append("e")
>>> c
['a', 't', 'e']
>>> b
['a', 't']
都是用了.copy()
为什么一个会影响 一个不会呢?

Twilight6 发表于 2020-6-21 16:43:34

本帖最后由 Twilight6 于 2020-6-21 18:17 编辑

举些例子吧,先看看这两拷贝的区别:

这里我们用Python内置函数 id() 来查看他们的内存地址是否相同,相同说明是同一个数据
import copy

l = [,1,2,3]
x = copy.copy(l)   # 浅拷贝:这里相当于列表切片[:]
z = copy.deepcopy(l)# 深拷贝
print('   原列表id地址:',id(l),'\n浅拷贝列表id地址:',id(x),'\n深拷贝列表id地址:',id(z))

运行结果:
   原列表id地址: 1708146868416
浅拷贝列表id地址: 1708149001152
深拷贝列表id地址: 1708149000448
三个列表的 id 全部不相同,说明浅拷贝是直接创建了新的列表,那列表内的元素呢?我们接下来看看下面的运行情况:

import copy

l = [,1,2,3]
x = copy.copy(l)   # 浅拷贝:这里相当于列表切片[:]
z = copy.deepcopy(l)# 深拷贝
print('   原列表内元素id地址:',id(l),'\n浅拷贝列表内元素id地址:',id(x),'\n深拷贝列表内元素id地址:',id(z))

运行结果:
   原列表内元素id地址: 2351807077120
浅拷贝列表内元素id地址: 2351807077120
深拷贝列表内元素id地址: 2351808203584

会发现浅拷贝的元素id和原来列表id相同,所以浅拷贝没有列表内的元素进行拷贝

而深拷贝的元素id与原先列表不同,所以深拷将列表内的元素彻彻底底的进行拷贝了

简单的说,就是深拷贝是完完全全的复制一遍,然后创建了新的列表,而浅拷贝只复制了列表的外壳,而内部元素还是没有拷贝成新的~

要注意的是:这些拷贝对所有可变类容器的来说都有这种性质,比如:列表、元组、字典、集合



Stubborn 发表于 2020-6-21 16:45:43

Twilight6 发表于 2020-6-21 16:43
举些例子吧,先看看这两拷贝的区别:

这里我们用Python内置函数 id() 来查看他们的内存地址是否相同,相 ...

列表的[:]会返回一个新的列表,可不是‘浅拷贝哦’

Twilight6 发表于 2020-6-21 16:46:20

Stubborn 发表于 2020-6-21 16:45
列表的[:]会返回一个新的列表,可不是‘浅拷贝哦’

浅拷贝也是返回新列表啊{:10_250:}

Twilight6 发表于 2020-6-21 16:51:33

Stubborn 发表于 2020-6-21 16:45
列表的[:]会返回一个新的列表,可不是‘浅拷贝哦’

对列表进行[:] 操作 就可以等价对列表进行浅拷贝,这点我敢肯定我没错

今天的我更强了 发表于 2020-6-21 17:19:08

Twilight6 发表于 2020-6-21 16:43
举些例子吧,先看看这两拷贝的区别:

这里我们用Python内置函数 id() 来查看他们的内存地址是否相同,相 ...

所以说
list1=
list2=
dict1={'1':list1,'2':list2}
dict2=dict1.copy()
dict1['1']=5
result=dict1['1']+dict2['1']
print(result)
print(dict2)
这个字典是内部子元素发生改变,会影响另外一方

c = b.copy()
>>> c.append("e")
>>> c
['a', 't', 'e']
>>> b
['a', 't']
这一个是表层的改变 不会相互影响 是这样么?

Stubborn 发表于 2020-6-21 17:19:42

Twilight6 发表于 2020-6-21 16:51
对列表进行[:] 操作 就可以等价对列表进行浅拷贝,这点我敢肯定我没错

我记错了{:10_262:}

今天的我更强了 发表于 2020-6-21 17:19:43

Stubborn 发表于 2020-6-21 16:38
理解一下,纸片(不可变类型数据),和纸盒(可变类型数据)的区别

当指针改变了指向,指向新的“纸片” ...

好的 我看看 谢谢

Twilight6 发表于 2020-6-21 17:23:15

今天的我更强了 发表于 2020-6-21 17:19
所以说
list1=
list2=


容器类型都是一样的 不管是字典 还是 列表,浅拷贝对容器来说是重新创建了一个新容器,但是对容器内的元素来说并没有

容器互不影响,但是当时的浅拷贝时候的可变元素会相互影响,不可变元素是不会的

今天的我更强了 发表于 2020-6-21 17:23:55

Twilight6 发表于 2020-6-21 17:23
容器类型都是一样的 不管是字典 还是 列表,浅拷贝对容器来说是重新创建了一个新容器,但是对容器内的元 ...

懂了 谢谢

Twilight6 发表于 2020-6-21 17:25:19

今天的我更强了 发表于 2020-6-21 17:23
懂了 谢谢

你应该设置我之前又长又粗的那个为最佳 {:10_266:} 我好不容易感觉写的好好哈哈哈哈哈

今天的我更强了 发表于 2020-6-21 17:28:17

Twilight6 发表于 2020-6-21 17:25
你应该设置我之前又长又粗的那个为最佳我好不容易感觉写的好好哈哈哈哈哈

这.能改吗?

Twilight6 发表于 2020-6-21 17:28:44

今天的我更强了 发表于 2020-6-21 17:28
这.能改吗?

没事 我和你开玩笑哪~~~{:10_281:}

今天的我更强了 发表于 2020-6-21 17:29:42

Twilight6 发表于 2020-6-21 17:28
没事 我和你开玩笑哪~~~

{:10_297:}
页: [1]
查看完整版本: 浅拷贝和深拷贝