【1】可变类型与不可变类型
在Python中,数据类型可以分为可变类型(Mutable)和不可变类型(Immutable)。这指的是对象在创建后是否可以更改其值或状态。
不可变类型是指创建后不能更改其值或状态的对象。如果对不可变类型的对象进行修改,将会创建一个新的对象,原始对象的值保持不变。在修改后,对象的身份标识(即内存地址)会发生变化。
以下是Python中常见的不可变类型:
整数(Integer)
浮点数(Float)
布尔值(Boolean)
字符串(String)
元组(Tuple)
可变类型是指可以在原地修改的对象,即可以改变其值或状态。当对可变类型的对象进行修改时,不会创建新的对象,而是直接修改原始对象。在修改后,对象的身份标识(即内存地址)保持不变。
Python中常见的可变类型:
列表(List)
字典(Dictionary)
对于可变类型,可以通过方法调用或索引赋值进行修改,而不会改变对象的身份标识。而对于不可变类型,任何修改操作都会创建一个新的对象。
【2】可变类型的存储方式
l = [1,2,3] # 存储
【3】可变类型的变量传递
变量实际上是对对象的引用。变量传递的核心是两个变量引用同一地址空间。
# 案例1:
x = 1
y = x
x = 2
print(y) # 1
print(id(x)) # 140710087838168
print(id(y)) # 140710087838136
# 案例2:
l1 = [1, 2, 3]
l2 = l1 # 变量传递
l1[0] = 100
print(l1, l2) # [100, 2, 3] [100, 2, 3]
l2[1] = 200
print(l1, l2) # [100, 200, 3] [100, 200, 3]
print(id(l1)) # 2031707148672
print(id(l2)) # 2031707148672
# 案例3:
l1 = [1, 2, 3]
l2 = [l1, 4, 5] # 也属于变量传递
l1[0] = 100
print(l1, l2) # [100, 2, 3] [[100, 2, 3], 4, 5]
l2[0][1] = 200
print(l1, l2) # [100, 200, 3] [[100, 200, 3], 4, 5]
print(id(l1)) # 2003477188992
print(id(l2)) # 2003477190848
【4】列表的深浅拷贝
在Python中,列表的拷贝可以分为深拷贝和浅拷贝两种方式。
浅拷贝(Shallow Copy)是创建一个新的列表对象,该对象与原始列表共享相同的元素对象。当你对其中一个列表进行修改时,另一个列表也会受到影响。
你可以使用以下方法进行浅拷贝:
# (1)使用切片操作符[:]进行拷贝:
l1 = [1, 2, 3, 4, 5]
l = l1[:]
print(l) # [1, 2, 3, 4, 5]
# (2)使用list()函数进行拷贝
l2 = [1, 2, 3, 4, 5]
l = list(l2)
print(l) # [1, 2, 3, 4, 5]
# (3)使用copy()方法进行拷贝(需要导入copy模块)
l3 = [1, 2, 3, 4, 5]
l = l3.copy()
print(l) # [1, 2, 3, 4, 5]
场景应用:
# 案例1
l1 = [1, 2, 3]
l2 = l1[:] # 浅拷贝
print(l2) # [1, 2, 3]
print(id(l1[0])) # 140710087838136
print(id(l2[0])) # 140710087838136
l1[1] = 300
print(l1) # [1, 300, 3]
print(l2) # [1, 2, 3]
# 案例2
l = [4, 5]
l1 = [1, 2, 3, l]
l2 = l1[:]
l1[0] = 100
print(l2) # [1, 2, 3, [4, 5]]
l1[3][0] = 400
print(l2) # [1, 2, 3, [400, 5]]
l1[3] = 400
print(l2) # [1, 2, 3, [400, 5]]
深拷贝(Deep Copy)是创建一个新的列表对象,并且递归地复制原始列表中的所有元素对象。这意味着原始列表和深拷贝的列表是完全独立的,对其中一个列表的修改不会影响另一个列表。
你可以使用copy()
模块中的deepcopy()
函数进行深拷贝:
import copy
original_list = [1, 2, 3, 4, 5]
deep_copy = copy.deepcopy(original_list)
print(original_list) # [1, 2, 3, 4, 5]
print(deep_copy) # [1, 2, 3, 4, 5]
print(id(original_list)) # 2953231194304
print(id(deep_copy)) # 2953231192448
需要注意的是,深拷贝可能会更耗费内存和时间,特别是当拷贝的列表中包含大量嵌套的对象时。