python学习---浅拷贝与深拷贝的关键点

1. python 可变与不可变对象

可变对象:指向地址不变,内容改变(原指向内存地址修改内容)
不可变对象:指向地址改变,内容改变(原指向地址不能改,重新开辟新的内存地址保持,所以地址与内容都发生改变)
  • 可变对象:list dict set
  • 不可变对象:tuple string int float bool

2. 浅拷贝与深拷贝

  第一个注意点:

  • 对于不可变对象来说,赋值操作其实就可以满足上面说的实际应用场景
  • 所以!后面要讲的浅拷贝、深拷贝对于不可变对象来说,和赋值操作是一样的效果!
  • 记住!浅拷贝、深拷贝针对可变对象,即列表、集合、字典!

3.浅拷贝: copy

一句话概括:浅拷贝会创建一个新对象,该新对象存储原始元素的引用,指向的对象并不是同一个

  • 浅拷贝后的值是相同的
  • 浅拷贝后的会产生一个新的对象

3.1.修改列表内的可变元素

import copy

old = [[1, 2], [3, 4]]
new = copy.copy(old)
print("old list", id(old))

old.append([5, 6])
old[1][1] = 44

print("Old list:", old, "id is :", id(old))
print("New list:", new, "id is :", id(new))

运行结果:
old list 21217408
Old list: [[1, 2], [3, 44], [5, 6]] id is : 21217408
New list: [[1, 2], [3, 44]] id is : 21218128

浅拷贝会开辟新的内存地址,新的变量会指向新内存地址

列表里面的元素(可变元素)地址则指向同一个内存地址,修改旧的列表元素,则两个都发生改变

3.2 修改列表内的不可变对象元素

import copy

old = [1, 2, "string", (1, 2,)]
new = copy.copy(old)
print("old list", id(old))

old.append([5, 6])
old[1] += 22
old[2] += "s"
old[3] += (44,)

print("Old list:", old, "id is :", id(old),id(old[3]))
print("New list:", new, "id is :", id(new),id(new[3]))

运行结果:
old list 30941232
Old list: [1, 24, 'strings', (1, 2, 44), [5, 6]] id is : 30941232 30884088
New list: [1, 2, 'string', (1, 2)] id is : 30887848 29210144

对于不可变对象,列表对象与列表里面的元素都不会指向相同的地址

4. 深拷贝:deepcopy

  • 创建一个新对象,且存储的对象引用也是新的
  • 深,意味着会把所有子元素对象也复制生成一个新对象

 

import copy

old = [[1, 2], [3, 4]]
new = copy.deepcopy(old)
print("old list", id(old))

old.append([5, 6])

print("Old list:", old, "id is :", id(old),id(old[1]))
print("New list:", new, "id is :", id(new),id(new[1]))

运行结果:
old list 27705512
Old list: [[1, 2], [3, 4], [5, 6]] id is : 27705512 27667512
New list: [[1, 2], [3, 4]] id is : 27706232 27705872
  • 两个变量保存了不同的对象引用
  • 可变对象元素(子对象)的内存地址也是不同的

参考文章:https://www.cnblogs.com/poloyy/p/15084277.html

posted @ 2022-03-14 16:04  沙丘蚂蚁慢慢爬  阅读(48)  评论(0编辑  收藏  举报