python中字典的直接赋值、浅拷贝和深拷贝

在python中进行字典的赋值的时候发现了一个问题:

有一个列表b=[{'a':1,'b':2}],列表b中现在只有一个字典{‘a':1,'b':2}。

现在要在b中添加另一个字典,这个字典的key和b中现有字典的key一样,但是value是它的两倍。

于是我写了下面这段代码:

b=[{'a':1,'b':2}]

c=b[0]

for x,y in c.items():
    c[x]=y*2
b.append(c)
print(b)

本来期待它能够输出[{'a': 1, 'b': 2}, {'a': 2, 'b': 4}],可是运行后b的值是这样的:[{'a': 2, 'b': 4}, {'a': 2, 'b': 4}],

b中原来的字典也改变了。如果要让b中原来的字典不改变就需要用到深拷贝(在这个例子中浅拷贝也可以)。

 

现在来了解一下直接赋值、浅拷贝和深拷贝:

1.直接赋值

上面代码中c=b[0]其实是给b[0]对象取了一个别名,也就是说c和b[0]指向同一个对象,所以c修改后b[0]也被修改了。

(和c++中的引用很像)

代码和运行结果:


b=[{'a':1,'b':2}]

c=b[0]

for x,y in c.items():
    c[x]=y*2
b.append(c)
print(b)


#输出结果是[{'a': 2, 'b': 4}, {'a': 2, 'b': 4}]

 

 

2.浅拷贝

调用b[0]对象的copy()函数就可以获得一个b[0]的浅拷贝对象。

比如:c=b[0].copy()

这样一来,如果b[0]中value是简单值而不是容器的话,那么对c的修改不会改变b[0]。

因为对于简单值,浅拷贝复制的是值本身,所以并不会改变原来的对象。

 

代码和运行结果:


b=[{'a':1,'b':2}]

c=b[0].copy()

for x,y in c.items():
    c[x]=y*2
b.append(c)
print(b)

#[{'a': 1, 'b': 2}, {'a': 2, 'b': 4}]

 

 

但是如果b[0]对象中value的值是一个容器(比如一个列表),那么对c的修改就会改变b[0]的值。

因为对于容器,拷贝的是别名,所以他们是指向同一个容器的,那么改变c自然后改变b[0]

 

代码:


b={'a':1,'b':[1,2]}

c=b.copy()

c['a']=2
c['b'].remove(1)

print(b)

#输出{'a': 1, 'b': [2]}

 

3.深拷贝

如:c=copy.deepcopy(b[0])   #需要导入copy 

这样拷贝后c和b[0]就完全是两个不同的对象,他们之间没有任何关系,即使b[0]中的value是一个容器,修改c也不会对b[0]产生任何影响。

 

代码:

import copy

b={'a':1,'b':[1,2]}

c=copy.deepcopy(b)

c['a']=2
c['b'].remove(1)

print(b)

#输出{'a': 1, 'b': [1, 2]}

 

 

 

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值