python列表的赋值复制深拷贝及浅拷贝

描述

  • 在Python的列表、字典里有很多的概念,像赋值、复制、深拷贝、浅拷贝。

赋值

  • 一般来说,对于普通变量x,y,直接把x值赋给y就能让两个变量相同
>>> x = 1
>>> id(x)
2093991856
>>> y = x   # 将x值直接赋给y,也就是让x和y指向同一个内存地址
>>> id(y)
2093991856
>>> y = 2   # 改变y的值
>>> id(y)   # y指向了新的内存地址
2093991872
>>> x       # x值没有变化
1
>>> id(x)
2093991856  # 内存地址也没有变
  • 上面普通的变量通过赋值可以实现复制的功能,但像列表,字典这种可变类型就不一样了:
>>> a_list = [1,2,3]
>>> id(a_list)
62615240
>>> b_list = a_list # 通过赋值把a_list的值给b_list
>>> id(b_list)      # 他们指向同一内存地址
62615240
>>> a_list[0] = 4   # 通过下标修改a_list的值
>>> a_list
[4, 2, 3]
>>> id(a_list)
62615240
>>> b_list      # b_list的值也跟着改变了
[4, 2, 3]
>>> id(b_list)
62615240
  • 这是因为列变量指向的是列表所在的内存地址,a_list和b_list都是指向同一个内存地址,因此列表中任意一个元素的变化,都会影响这两个列表的值跟着变化。那么怎么要这两个列表独立分开呢,就得用上列表的浅拷贝功能了

浅拷贝

通过切片拷贝

>>> a_list = [1,2,3]
>>> id(a_list)
62615048
>>> b_list = a_list[:]  # 通过切片b_list复制a_list的值
>>> id(b_list)      # 切片复制的b_list是指向了一个新的内存地址
62615496
>>> b_list
[1, 2, 3]
>>> b_list[0] = 4   # 通过下标修改b_list的值
>>> b_list
[4, 2, 3]
>>> id(b_list)
62615496
>>> a_list  # a_list没有改变
[1, 2, 3]
>>> id(a_list)
62615048

通过list()函数复制

>>> a_list = [1,2,3]
>>> id(a_list)
62615208
>>> b_list = list(a_list)
>>> id(b_list)
56270600
>>> b_list
[1, 2, 3]
>>> b_list[0] = 4
>>> b_list
[4, 2, 3]
>>> a_list
[1, 2, 3]

通过列表extend()方法复制

>>> a_list = [1,2,3]
>>> id(a_list)
47685160
>>> b_list = []
>>> b_list.extend(a_list)
>>> id(b_list)
54012712
>>> b_list
[1, 2, 3]
>>> b_list[0] = 4
>>> b_list
[4, 2, 3]
>>> a_list
[1, 2, 3]

通过copy模块来复制

>>> import copy
>>> a_list = [1,2,3]
>>> id(a_list)
54013288
>>> b_list = []
>>> b_list = copy.copy(a_list)
>>> id(b_list)
54012712
>>> b_list
[1, 2, 3]
>>> b_list[0] = 4
>>> b_list
[4, 2, 3]
>>> a_list
[1, 2, 3]

通过列表解析(列表推导)

>>> a_list = [1,2,3]
>>> b_list = [i for i in a_list]
>>> b_list[0] = 4
>>> b_list
[4, 2, 3]
>>> a_list
[1, 2, 3]

深拷贝

  • 从上面几种拷贝方法可以看出,a_list和b_list列表是两个相互独立的变量,也成功实现了复制功能,那么为什么说这些是浅拷贝呢,如下 :
>>> a_list = [1,2,3,['a','b']]  # 二维列表
>>> b_list = a_list[:]
>>> b_list
[1, 2, 3, ['a', 'b']]
>>> a_list[0] = 4   # 修改普通元素
>>> a_list
[4, 2, 3, ['a', 'b']]
>>> b_list      # 可以看出,b_list没有影响
[1, 2, 3, ['a', 'b']]
>>> a_list[3][-1] = 5   # 修改子列表内的元素
>>> a_list
[4, 2, 3, ['a', 5]]
>>> b_list      # b_list也跟着改变了
[1, 2, 3, ['a', 5]]
  • 如上可知,使用这种复制的列表,一旦涉及到列表中有多维列表时,修改其子列表时,所有列表的子列表都会跟着修改。
  • 要想实现不管多少维度的列表都能完全独立的话,就需要用到Python标准库中copy库提供的deepcopy函数了,这就是深拷贝,如下:
>>> import copy     # 引入copy库
>>> a_list = [1,2,3,['a','b']]
>>> b_list = copy.deepcopy(a_list)  用函数deepcopy实现深拷贝
>>> b_list
[1, 2, 3, ['a', 'b']]
>>> a_list[3][-1] = 5
>>> a_list
[1, 2, 3, ['a', 5]]
>>> b_list  # b_list值没有跟着改变
[1, 2, 3, ['a', 'b']]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值