IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> python赋值浅拷贝深拷贝的不同 -> 正文阅读

[Python知识库]python赋值浅拷贝深拷贝的不同

python中所有的事物都是对象

一:赋值

首先看下面这个例子,id查看对象的地址

x = 666
id(x)  # 2650482715088
y = x
id(y)  # 2650482715088

因为y=x只是把y指向了x指向的对象,那你可能会好奇,修改x,那么y会一起变化吗?其实是不会的,因为当你修改x的时候其实是创建了一个新的对象,并把x指向这个对象

x = 666
id(x)  # 2650482966608
y = x
id(y)  # 2650482966608
x=x+1
id(x)  # 2650482967344
id(y)  # 2650482966608
print(y)  # 666

但是这只针对不可变对象(int,string等)可变对象(list等)是会发生改变的。因为不可变对象发生改变时其实是创建了新的对象并赋值

x=[1,2,3]
y=x
id(x)  # 2650483005960
id(y)  # 2650483005960
x.append(5)
id(x)  # 2650483005960
id(y)  # 2650483005960
print(x)  # [1, 2, 3, 5]
print(y)  # [1, 2, 3, 5]

但是如果是显示的改变可变对象,不会影响y的值

x = [1,2,3]
id(x)  # 2650482808648
y = x
id(y)  # 2650482808648
x = x + [4]
id(x)  # 2650482864712
print(x)
print(y)
"""
[1, 2, 3, 4]
[1, 2, 3]
"""

因为实际上是新建了一个对象[1,2,3,4]并让x指向这个新的对象

2 缓存池

再看下面的例子,x和y指向相同的对象

x = 666
y = x
id(x)  #  2040304935632
id(y)  #  2040304935632

而下面则不同

a = 888
id(a)  # 2650482715440
b = 888
id(b)  # 2650482715568

因为是创建了两个对象,分别赋值给a,b

  • 第一次 : 仅仅在内存中创建一个整型对象666, xy都是这个整型对象的标签
  • 第二次 : 在内存中创建两个整型对象888,分别用ab作为标签

注意:python有小整数池(-5 ~ 256)

x=2
y=2
id(x)  # 140736101317728
id(y)  # 140736101317728

对于xy这样小的且常用的整型值,python在内存中并不是创建两个对象,而是一个对象.此时xy都是整型对象2的标签。python的小整数池是为了提高缓存效率,降低’常用’对象频繁创建撤销频率

类似的,字符串也有缓存池,缓存机制符合一下规则

字符串都会被缓存复用,但是只能是字母和数字和下划线构成的

s1="sssjkjksTjasdfgssshjkl哈"
len(s1)
s2="sssjkjksTjasdfgssshjkl哈"
id(s1)  # 2040304847280
id(s2)  # 2040304847664
s1 is s2  #  False
s1="sssjkjks1Tjasdfgssshjklssssssss_"
len(s1)
s2="sssjkjks1Tjasdfgssshjklssssssss_"
id(s1)  # 2040305172928
id(s2)  # 2040305172928
s1 is s2

接下来就是浅拷贝和深拷贝

浅拷贝和深拷贝

首先回顾一下刚才讲的赋值

abc=[1,'string',['python','java',25]]
zxc=abc
id(abc)  # 2040305182344
id(zxc)  # 2040305182344

到目前为止可能没什么疑问,修改里面的值,abc,zxc都会一起变化

abc[0]=2
abc[2].append(5)
print(abc)
print(zxc)
"""
[2, 'string', ['python', 'java', 25, 5]]
[2, 'string', ['python', 'java', 25, 5]]
"""

但是注意

abc=[1,'string',['python','java',25]]
zxc=abc
id(abc)  
id(zxc)  
print([id(x) for x in abc])
print([id(x) for x in zxc])
"""
[140736101317696, 2042134608752, 2040305268936]
[140736101317696, 2042134608752, 2040305268936]
"""
abc[0]=2
abc[2].append(5)
print(abc)
print(zxc)
"""
[2, 'string', ['python', 'java', 25, 5]]
[2, 'string', ['python', 'java', 25, 5]]
"""
print([id(x) for x in abc])
print([id(x) for x in zxc])
"""
[140736101317728, 2042134608752, 2040305268936]
[140736101317728, 2042134608752, 2040305268936]
"""

注意:这里abc[0]的地址是变化了,但是abc[2]的地址不变(因为int是不可变对象 修改意味着创建新的对象并赋值,而list是可变对象)

请添加图片描述

接下来是浅拷贝

abc=[1,'string',['python','java',25]]
zxc=copy.copy(abc)
id(abc)  # 2040305143752
id(zxc)  # 2040321956104
print([id(x) for x in abc])
print([id(x) for x in zxc])
"""
[140736101317696, 2042134608752, 2040305323016]
[140736101317696, 2042134608752, 2040305323016]
"""

注意到abc和zxc的地址已经不同了,但是它们里面元素的地址还是指向相同的地址

abc[0]=2
abc[2].append(5)

print(abc)
print(zxc)
"""
[2, 'string', ['python', 'java', 25, 5]]
[1, 'string', ['python', 'java', 25, 5]]
"""
print([id(x) for x in abc])
print([id(x) for x in zxc])
"""
[140736101320832, 2042134608752, 2040305323016]
[140736101317696, 2042134608752, 2040305323016]
"""

abc[0]的地址和zxc[0]的地址不同了,值也不同了
请添加图片描述

深拷贝

abc=[1,'string',['python','java',25]]
zxc=copy.deepcopy(abc)
id(abc)  # 2326337710920
id(zxc)  # 2326338046664
print([id(x) for x in abc])
print([id(x) for x in zxc])
"""
[140736246742080, 2326022994736, 2326340682056]
[140736246742080, 2326022994736, 2326340706824]
"""
abc[0]=99
abc[2].append(5)
print(abc)
print(zxc)
"""
[99, 'string', ['python', 'java', 25, 5]]
[1, 'string', ['python', 'java', 25]]
"""
print([id(x) for x in abc])
print([id(x) for x in zxc])
"""
[140736246745216, 2326022994736, 2326340682056]
[140736246742080, 2326022994736, 2326340706824]
"""

在这里插入图片描述

注意:对于非容器类型(如数字、字符串、和其他’原子’类型的对象)没有拷贝这一说

总结:

"abc=zxc"赋值时,没有开辟新的内存空间,所有变量的修改都会互相影响

浅拷贝:对abc非可变对象的修改不会影响到zxc,但对可变对象的修改会影响到zxc

深拷贝:所有变量的修改都不会互相影响

浅拷贝的情况:

1 切片zxc=abc[:]

2 copy.copy

深拷贝的情况:

1 copy.deepcopy

2 DataFrame.copy()

参考资料:
1图解python中赋值、浅拷贝、深拷贝的区别
2 Python: 函数参数是值传递还是引用传递?
3 可变对象和不可变对象

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-05-16 11:18:33  更:2022-05-16 11:19:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 13:28:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码