app开发者平台在数字化时代的重要性与发展趋势解析
704
2022-11-22
Python的copy
深浅copy
浅copy():如果原列表都是不可变类型,使用浅copy即可。(浅copy:对列表第一层地址拷贝)
深copy():如果愿列表有可变类型存在(如列表里嵌套一个列表),使用深copy。(深copy:对列表的第一层和第二层拷贝)
实战:
需求:定义一个列表
# 定义一个列表l1 = ["egon", 'lxx', [1, 2]]# 索引 0 1 2
如图所示:
在栈区中开辟:变量名l1关联列表的内存地址0xffff0030,共同指向堆区
在堆区中开辟:索引是0 的内存地址0xffff1111它指向的值为‘egon’,
索引是1 的内存地址0xffff2222它指向的值为‘lxx’,
索引是2 的内存地址0xffff3333它指向的是子列表[1,2]的内存地址。
子列表在堆区中又开辟:
索引是0 的内存地址0xffff4441它指向的值为1
索引是0 的内存地址0xffff5551它指向的值为2
# 定义一个列表l1 = ["egon", 'lxx', [1, 2]]print(l1)print(id(l1)) # 31342344# l1 赋给 l2l2 = l1print(l2)print(id(l2)) # 31342344
在栈中开辟:变量名l2关联列表的内存地址0xffff0030,指向l1指向的堆区。
# l1改变了,l2也变了,互相操作则互相影响。l1[0] = 'lsj'print(l1,l2) # ['lsj', 'lxx', [1, 2]] ['lsj', 'lxx', [1, 2]]print(id(l1),id(l2)) # 31276808 31276808
需求:
如果我想创建一个列表l3,复制列表l1的内容,使其修改操作独立分开,当互相操作时互不影响,该怎么办?
提炼需求:1、拷贝一下列表,产生新的需求。
2、想让两个列表完全独立开(针对改操作)。(读的操作有意义么?--没有)
这就用到了copy:我们先验证浅copy()行不行?
# 浅copy(),先定义一个列表l1 = ["egon", 'lxx', [1, 2]]print(l1) # ['egon', 'lxx', [1, 2]]print(id(l1)) # 34815880# 进行copy()l3 = l1.copy()print(l3) # ['egon', 'lxx', [1, 2]] 证明l3的值和l1的值相同print(id(l1),id(l3)) # 34815880 34815944
print(id(l1[0]),id(l1[1]),id(l1[2])) # 34865312 37715448 34881480print(id(l3[0]),id(l3[1]),id(l3[2])) # 34865312 37715448 34881480
# 拷贝完后修改l1的值查看l3的值变化没有?l1[0] = 'EGON' # 针对不可变类型修改其值l1[1] = 'LXX'
# l1[2] = 123# print(l1,l3) # ['EGON', 'LXX', 123] ['egon', 'lxx', [1, 2]] 证明l1变了,l3没有变l1[2][0] = 111 # 针对可变类型修改其值l1[2][1] = 222print(l1,l3) # 但是当子列表值修改后['EGON', 'LXX', [111, 222]] ['egon', 'lxx', [111, 222]] l1,l3的值都变了
解析:当l3 = l1.copy()证明l1的值拷贝到了l3
在栈区中开辟:变量名l3关联列表的内存地址0xffff6666,共同指向堆区
在堆区中开辟:索引是0 的内存地址0xffff1111它指向的值为‘egon’,
索引是1 的内存地址0xffff2222它指向的值为‘lxx’,
索引是2 的内存地址0xffff3333它指向的是子列表[1,2]的内存地址。
子列表在堆区中又开辟:
索引是0 的内存地址0xffff4441它指向的值为1
索引是1 的内存地址0xffff5551它指向的值为2
综上所述:浅copy:把列表第一层内存地址,不加区分(区分的是可变类型和不可变类型)完全拷贝到新的列表。
浅copy():如果原列表都是不可变类型,使用浅copy完全没问题。(浅copy:对列表第一层地址拷贝)
深copy():如果愿列表有可变类型存在(如列表),就会出问题。(深copy:对列表的第一层和第二层拷贝)
深copy:我要对列表里的数据类型区分,那就要用到deepcopy()
import copy# 深copy(),先定义一个列表l1 = ["egon", 'lxx', [1, 2]]l4 = copy.deepcopy(l1)print(id(l1),id(l4)) # 39260552 39261832# 深copy对可变类型地址拷贝一份。# 类型:不可变 不可变 可变print(id(l1[0]),id(l1[1]),id(l1[2])) # 34668704 35421688 39063752print(id(l4[0]),id(l4[1]),id(l4[2])) # 34668704 35421688 39065160
# 查看可变类型里的id地址print(id(l1[2][0]),id(l1[2][1])) # 492265696 492265728print(id(l4[2][0]),id(l4[2][1])) # 492265696 492265728
针对不可变类型就会使用原来的地址,针对不可变类型就会造一个新的地址
l1[0] = 'EGON'l1[1] = 'LXX'l1[2][0] = 111 # 原内存地址不变,创建一个新的值l1[2][1] = 222 # 原内存地址不变,创建一个新的值
print(l1,l4) # ['EGON', 'LXX', [111, 222]] ['egon', 'lxx', [1, 2]] # copy的列表值未变
结论:
如果我想拷贝一个新的列表,复制前一个列表的内容,要使其修改操作独立分开,要是用深copy。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~