python深拷贝浅拷贝

问题1: 将列表c添加到列表a,b之中,修改c中的值,a,b会变化吗?

a = list()
b = list()
c = [2,3]

a.append(c)
b.append(c)

print(a,b)
输出:[[2, 3]] [[2, 3]]
#修改C中第一个元素
c[0] = 1

print(a,b)
输出1:[[1, 3]] [[1, 3]] ,即改变c中元素,a,b也发生了变化

分析1

  • a,b,c都是容器类对象,当将一个容器A放到另外一个容器B里的时候,B中放的是A的引用,即A的地址。所以改变c,也会改变a,b

问题2:将变量d添加到列表a,b之中,改变da,b会变吗?

d = 9
a.append(d)
b.append(d)
print(a,b)
输出:[[1, 3], 9] [[1, 3], 9]
#改变d的值,考虑一下 a,b会变吗?
d = 10
print(a,b)
输出2:[[1, 3], 9] [[1, 3], 9] ,即改变da,b没有变化

分析2

  • d是数值类型,a,b是容器类型,将d放到(append)a,b中,a,b之中保存了d的引用,但是改变d的值,会重新分配一块内存空间,也就是说前后两个d,已经没有任何关系了。这样说可能不太好懂,我们看下面的列子:
a = 10
print(id(a))
a = 11
print(id(a))

#输出:
4544079472
4544079504

可见,只改变a的值,a的地址也发生了变化,即前后两个a,没有任何关系了。另外:前一个a如果没有其他对象引用的话,将会被回收。

python 数据类型

Python有五个标准的数据类型

  1. Numbers(数字)
  2. String(字符串)
  3. List(列表)
  4. Tuple(元组)
  5. Dictionary(字典)

其中,1,2代表数字常量或者字符串常量,常量表示不可以改变,如果想改变就要创建新的对象。如分析2所示。3,4,5代表容器类对象,存储的是常量引用或是其他容器的引用,修改他们区别,如上问题1,2所示。

字典的例子

下面是基于字典容器的例子,结论和上面的例子相同。

f = [1,2,3]
g = 10
#打印 f,g地址
print(f'g:{id(g)} f:{id(f)}')

d = {'one':g,'two':f}

#打印字典中对应的地址
print(f"d['one']:{id(d['one'])}  d['two']: {id(d['two'])}")
输出:
g:4392810096 f:4436990920
d['one']:4392810096  d['two']: 4436990920
f[1] = 20 #改变f中某个元素
g = 20 #改变g的值(注意创建了新的对象)

print(f"新g地址:{id(g)}, 字典中旧g地址:{id(d['one'])}")
print(d)
输出:
新g地址:4392810416, 字典中旧g地址:4392810096
{'one': 10, 'two': [1, 20, 3]}

python 中的copy和deepcopy

copy: 即shallow copy,容器中的常量换新,容器中的容器保留了引用。
deepcopy:容器中的所有内容全部换新。
举个栗子:

import copy
a = [1, 2, 3, 4, ['a', 'b']]  #原始对象

b = a  #赋值,传对象的引用
c = copy.copy(a)  #对象拷贝,浅拷贝
d = copy.deepcopy(a)  #对象拷贝,深拷贝

a.append(5)  #修改对象a
a[4].append('c')  #修改对象a中的['a', 'b']数组对象

print 'a = ', a
print 'b = ', b
print 'c = ', c
print 'd = ', d

输出结果:
a =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
b =  [1, 2, 3, 4, ['a', 'b', 'c'], 5]
c =  [1, 2, 3, 4, ['a', 'b', 'c']]
d =  [1, 2, 3, 4, ['a', 'b']]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值