12-python内存地址

本文详细介绍了Python中内存地址的概念,以及不可变数据类型(如字符串、数值)和可变数据类型(如列表、字典)在内存中的存储方式。重点讨论了浅拷贝和深拷贝的区别,包括它们在单层和嵌套数据结构中的表现,以及对数据修改的影响。浅拷贝通过赋值或`copy.copy()`创建,而深拷贝使用`copy.deepcopy()`,确保了数据的独立性。
摘要由CSDN通过智能技术生成

1.查看内存地址

a=1
print(id(a)) # 2431929483504

2.数据类型
(1)不可变数据类型:数值、字符串、布尔值、元组
数据存储在计算机中的某个位置,不管赋值给谁,内存地址都相同

a="jack"
b="jack"
print(id(a))
print(id(b))
# 输出结果相同

在此例中,为字符串“jack”定义了两个别名a和b(即变量名a,b是对字符串地址的引用),便于我们表示这个字符串

a="jack"
b="jack"
print(id(a))
print(id(b))
print(id("jack"))
# 输出均相同

(2)可变数据类型:列表、字典、集合
对于可变数据类型,内存会开辟不同的内存地址存放相同的数据

a=[1,2,3]
b=[1,2,3]
print(id(a))
print(id(b))
# 输出结果不同

3.数据修改
(1)不可变数据类型
不同数据存放的地址不同,会使变量指向不同的地址

a=1
print(id(a)) # 2546017632496
a=2
print(id(a)) # 2546017632528

(2)可变数据类型
对数据的修改可视为在原地址上对数据的修改,地址不会改变

a=[1,2,3]
print(id(a)) # 2287597971776
a.append(4)
print(id(a)) # 2287597971776

嵌套同样,在下例中,a和b的地址均未发生变化

a=[1,2]
b=[3,a]
print(id(b)) # 2509191607104
a.append(4) # 对a修改,b不受影响
print(id(b)) # 2509191607104

4.浅拷贝
(1)直接赋值
拷贝的是内存地址,其中任一个的值发生变化,另一个也会跟随变化

a=[1,2]
b=a
print(id(a))
print(id(b))
# 相同
a=[1,[2,3]]
b=a
print(id(a[1][0]))
print(id(a[1][0]))
# 相同

(2)copy方法
(2-1)地址空间
①不可变-单层:相同

import copy
a=2
b=copy.copy(a)
print(id(a),id(b)) # 2110693638416 2110693638416

②可变-单层:不同

import copy
a=[1,2]
b=copy.copy(a)
print(id(a),id(b)) # 2426879856704 2426879856640

③可变-嵌套:整体不同,内部相同

import copy
a=[1,2,[1,2]]
b=copy.copy(a)
print(id(a),id(b)) # 1649968533504 1649968533376
print(id(a[2]),id(b[2])) # 1649968533568 1649968533568
print(id(a[2][0]),id(b[2][0])) # 1649966448880 1649966448880

④不可变-嵌套:相同

import copy
a=(1,2,[1,2])
b=copy.copy(a)
print(id(a),id(b)) # 2199230674304 2199230674304
print(id(a[2]),id(b[2])) # 2199230992448 2199230992448
print(id(a[2][0]),id(b[2][0])) # 2199228907760 2199228907760

(2-2)修改
①单层-可变:互不影响

import copy
a=[1,2]
b=copy.copy(a)
a.append(3)
print(a) # [1, 2, 3]
print(b) # [1, 2]

②单层-不可变:互不影响

import copy
a=(1,2)
b=copy.copy(a)
a=(3,4)
print(a) # (3, 4)
print(b) # (1, 2)

③嵌套-外层可变-内层可变:相互影响

import copy
a=[1,2,[3,4]]
b=copy.copy(a)
a[2].append(5)
print(a) # [1, 2, [3, 4, 5]]
print(b) # [1, 2, [3, 4, 5]]

④嵌套-外层可变-内层不可变:互不影响
不便于对内部元组元素进行修改,互不影响

⑤嵌套-外层可变-外层修改:互不影响

import copy
a=[1,2,(3,4)]
b=copy.copy(a)
a.append(5)
print(a) # [1, 2, (3, 4), 5]
print(b) # [1, 2, (3, 4)]

⑥嵌套-外层不可变-内层可变:相互影响

import copy
a=(1,2,[3,4])
b=copy.copy(a)
a[2].append(5)
print(a) # (1, 2, [3, 4, 5])
print(b) # (1, 2, [3, 4, 5])

⑦嵌套-外层不可变-内层不可变:互不影响
不便于对内部元组元素进行修改,互不影响

⑧嵌套-外层不可变-外层修改:互不影响
不便于对内部元组元素进行修改,互不影响

import copy
a=(1,2,(3,4))
b=copy.copy(a)
a=list(a)
a[0]=6
a=tuple(a)
print(a) # (6, 2, (3, 4))
print(b) # (1, 2, (3, 4))
  • 对以上提到的可变数据类型的b=copy.copy(a)均可写为b=a.copy() (无需导包)

[练习1]

import copy
a=[1,[2,3]]
b=copy.copy(a)
print(id(a),id(b)) # 不同
print(id(a[1][0]),id(b[1][0])) # 相同

[练习2]

a=[1,[11,22,33],(5,6,7)]
b=a.copy()
print(id(a),id(b)) # 不同
print(id(a[0]),id(b[0])) # 相同
print(id(a[1]),id(b[1])) # 相同
print(id(a[1][0]),id(b[1][0])) # 相同
print(id(a[2]),id(b[2])) # 相同
print(id(a[2][0]),id(b[2][0])) # 相同

[练习3]

# 可变数据类型的外部修改:互不影响
a=[1,[11,22,33],(5,6,7)]
b=a.copy()
a.append(6)
print(a) # [1, [11, 22, 33], (5, 6, 7), 6]
print(b) # [1, [11, 22, 33], (5, 6, 7)]

# 可变数据类型的内部可变修改:相互影响
a=[1,[11,22,33],(5,6,7)]
b=a.copy()
a[1].append(6)
print(a) # [1, [11, 22, 33, 6], (5, 6, 7)]
print(b) # [1, [11, 22, 33, 6], (5, 6, 7)]

[练习4]

a={"age":18,"name":"black"}
b=a.copy()
c=a # 拷贝的是内存地址,影响

a["age"]=2000
print(b) # {'age': 18, 'name': 'black'}
print(c) # {'age': 2000, 'name': 'black'}

浅拷贝总结(根据实验数据得出,仅供参考)
修改:嵌套可变数据类型的修改会导致变量的值同时变化
地址:不可变相同,可变不同(嵌套内部相同)

在这里插入图片描述

(3)切片

a=[1,2,3]
b=a[0:2]
print(b) # [1, 2]
print(a) # [1, 2, 3]
# 对于切片的拷贝,不受影响

5.深拷贝
(1)内存地址
①单层不可变:相同

import copy
a=1
b=copy.deepcopy(a)
print(id(a),id(b)) # 相同

②单层可变:不同

import copy
a=[1,2,3]
b=copy.deepcopy(a)
print(id(a),id(b)) # 不同

③嵌套-外层可变
外层不同,内层相同

import copy
a=[(1,2),3,(4,5)]
b=copy.deepcopy(a)
print(id(a),id(b)) # 不同
print(id(a[0]),id(b[0])) # 相同
print(id(a[0][0]),id(b[0][0])) # 相同

④嵌套-外层不可变
全部相同

import copy
a=((1,2),3,(4,5))
b=copy.deepcopy(a)
print(id(a),id(b)) # 相同
print(id(a[0]),id(b[0])) # 相同
print(id(a[0][0]),id(b[0][0])) # 相同

因此,深拷贝与浅拷贝的内存地址完全一致

(2)修改
①可变-单层:互不影响

import copy
a=[1,2]
b=copy.deepcopy(a)
a.append(3)
print(a) # [1, 2, 3]
print(b) # [1, 2]

②不可变-单层:互不影响

import copy
a=2
b=copy.deepcopy(a)
a=3
print(a) # 3
print(b) # 2

③外层可变-内层可变-嵌套:互不影响

import copy
a=[1,2,[3,4]]
b=copy.deepcopy(a)
a[2].append(5)
print(a) # [1, 2, [3, 4, 5]]
print(b) # [1, 2, [3, 4]]

④外层可变-内层不可变-嵌套:互不影响

import copy
a=[1,2,(3,4)]
b=copy.deepcopy(a)
a[2]=a[2]+(5,)
print(a) # [1, 2, (3, 4, 5)]
print(b) # [1, 2, (3, 4)]

⑤外层可变-外层修改-嵌套:互不影响

import copy
a=[1,2,(3,4)]
b=copy.deepcopy(a)
a.append(5)
print(a) # [1, 2, (3, 4), 5]
print(b) # [1, 2, (3, 4)]

⑥外层不可变-内层可变-嵌套:互不影响

import copy
a=(1,[2,3],(4,5))
b=copy.deepcopy(a)
a[1].append(6)
print(a) # (1, [2, 3, 6], (4, 5))
print(b) # (1, [2, 3], (4, 5))

⑦外层不可变-内层不可变-嵌套:互不影响
不便于对元组修改,地址空间基本都会变化
⑧外层不可变-外层修改-嵌套:互不影响
不便于对元组修改

深拷贝总结:
修改:各变量独立
地址(与浅拷贝相同):不可变相同,可变不同(嵌套内部相同)

在这里插入图片描述

总结

在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡__卡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值