问题
da={'test':1}
dac=da
dct['test']=2
print(dac)
print(da)
输出:22
改动的是dac,但是da也跟着改变。
解释
字典da 是一个object ,python 为提高性能,优化内存,dac=da并没有真正的将该字典在内存中再次创建,只是指向了相同的object。如下:
da={"name":""}
l=[]
for i in range(5):
da["name"]=i
l.append(da)
print l
输出:[{‘name’: 4}, {‘name’: 4}, {‘name’: 4}, {‘name’: 4}, {‘name’: 4}]
对象append到list 中,但是list中存放的也是一个对象,或者说是字典的地址,而非内存中真正的存储空间。
dict(字典)赋给list的是一个位置,对于上述代码,dict定义在循环外,每次使用l.append(da)赋给 list的都是相同的位置,而在同一位置的da的值已经改变了,所以list取到的之前位置的值改变了,表现出后面数据覆盖前面数据的表象。dict定义在循环内,相当于每一次循环生成一个dict,占用不同的位置存储值,所以可以赋给list不同元素不同的位置,获得不同的值。
深层次解释:
Python中的对象之间赋值时是按引用传递的,如果需要拷贝对象,需要使用标准库中的copy模块。
解决方法
使用 .copy()方法。可以创建一个新的独立的字典
d={“name”:""}
l=[]
for i in xrange(5):
test=d.copy()
test[“name”]=i
l.append(test)
print l
da={"name":""}
l=[]
for i in range(5):
dac = dac.cpoy()
dac["name"]=i
l.append(dac)
print l
输出:[{‘name’: 0}, {‘name’: 1}, {‘name’: 2}, {‘name’: 3}, {‘name’: 4}]
新的问题
a={'q':1,'w':[]}
b=a.copy()
b['q']=2
b['w'].append(123)
print a
print b
a中’q’的值不会变化但是其列表中的值还是发生了改变
解释
- copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象。
- copy.deepcopy 深拷贝 拷贝对象及其子对象
解决方法
a={'q':1,'w':[]}
b=a.copy()
b['q']=2
b['w']=[123]
print a
print b
直接赋值的话,则不会改变a中的结构
import copy
a={'q':1,'w':[]}
b=copy.deepcopy(a)
b['q']=2
b['w']=[123]
print a
print b
使用deepcopy()深层次的copy