数据处理经常会用到引用或者赋值,Python中的可变类型变量在操作时需要注意拷贝的方式,特别在实现复杂功能的函数时,一不小心就会改变原来的数据内容。
data = {
"name":"anne",
"age":18,
"scores":{
"语文":130,
"数学":150,
"英语":120}
}
d2 = data
data["age"] = 20
print(d2)
d2打印的值里,age是18,还是20?
{'name': 'anne', 'age': 20,
'scores': {'语文': 130, '数学': 150, '英语': 120}}
为何是20呢?因为d2=data相当于只是拿到了data的内存地址,但data里的每个k,v都是有单独的内存的地址的。d2,data会一直共享这个dict里的数据。
如果只想复制一份完成的dict数据怎么办呢?
可以用浅copy语法
d2 = data.copy()
data["age"] = 20
print(d2)
print(data)
{'name': 'anne', 'age': 18,
'scores': {'语文': 130, '数学': 150, '英语': 120}}
{'name': 'anne', 'age': 20,
'scores': {'语文': 130, '数学': 150, '英语': 120}}
但是为什么这个语法叫做浅copy呢?你改一下score里的值 就知道了。
d2 = data.copy()
data["age"] = 20
data["scores"]["数学"] = 99
print(d2)
print(data)
看输出 , 很神奇,两个Dict里age的值是独立的,但score字典里的分数值貌似是共享的。
{'name': 'anne', 'age': 18,
'scores': {'语文': 130, '数学': 99, '英语': 120}}
{'name': 'anne', 'age': 20,
'scores': {'语文': 130, '数学': 99, '英语': 120}}
因为浅copy会仅复制dict的第一层数据,更深层的scores下面的值依然是共享一份。
深deepcopy
若你想彻底使上面的2个dict完全独立,无论有多少层数据。那就要用python工具包里的一个工具了。
总结:
一维数组尽量用浅拷贝。
如下形参 x 的改变会影响到原 nums,因为形参 x 虽然名字变了,但实际上还是对原 nums 的引用,他们指向同一内存地址,在调用 addStr(x) 之后原nums 就发生了变化,此时当你想取到元素 3,用 nums[-1] 是错误的,正确做法是先进行浅拷贝:
1. 可以在调用 addStr(nums[:]) 时候就进行浅拷贝。
2. 也可以在执行 addStr(x)时候,先用局部变量做一个浅拷贝。
def addStr(x):
# x = x[:] # 先用一个局部变量进行浅拷,贝就正确了
x.append('a')
nums = [1, 2, 3]
addStr(nums)
print(nums[-1]) # 'a', 因为此时 nums = [1, 2, 3, 'a']
多维数组的使用尽量用深拷贝
nums = [[0] * 3 for _ in range(2)]
tmp = nums[:]
# tmp = copy.deepcopy(nums) # 正确用法
tmp[0][0] = 3