1.可变与不可变数据类型
1.1 immutable:
不可变数据类型指的是一旦创建,其值就不能被改变的数据类型。在Python中,常见的不可变数据类型包括:
int
(整数)float
(浮点数)complex
(复数)str
(字符串)tuple
(元组)
示例:
代码语言:javascript复制if __name__ == '__main__':
age = 25
print(age, id(age))
num = age
print(id(num), id(age))
num = 30
print(f'immutable: {age=} {num=} id(age)={id(age)} id(num)={id(num)}')
--------------------------------
25 140713717812408
# age 和 num 的地址相同
140713717812408 140713717812408
# num重新赋值后 num的地址变了 age的值没变地址没变
immutable: age=25 num=30 id(age)=140713717812408 id(num)=140713717812568
总结:数据类型的值变了,内存地址也变了,这种数据类型为不可变。
1.2 mutable:
可变数据类型允许你在创建后修改其值。Python中的可变数据类型包括:
list
(列表)dict
(字典)set
(集合)bytearray
(字节数组)
示例:
代码语言:javascript复制if __name__ == '__main__':
列表 = ['北京', '上海', '深圳', '广州']
print(f'origin 列表 {列表} id(列表) = {id(列表)}')
列表.append('太原')
print(f'modified 列表 {列表} id(列表) = {id(列表)}')
--------------------------------
origin 列表 ['北京', '上海', '深圳', '广州'] id(列表) = 2449677930880
modified 列表 ['北京', '上海', '深圳', '广州', '太原'] id(列表) = 2449677930880
总结:数据类型的值变了,内存地址没变,这种数据类型为可变。
2. 浅拷贝与深拷贝
2.1 shallow copy:
在Python中,你可以使用copy
模块的copy()
函数或切片操作来实现浅拷贝。拷贝后的对象与源对象是两个独立的对象,如果源对象中包含可变对象,浅拷贝只拷贝可变对象的引用而非可变对象本身,所以修改可变对象会同时作用于源对象和拷贝后对象。
示例:
代码语言:javascript复制import copy
if __name__ == '__main__':
省 = ['山西', '河北', '河南', '山东', '吉林', '一线']
市 = ['太原', '石家庄', '郑州', '济南', '长春', []]
字典 = dict(zip(省, 市))
print(字典)
temp = copy.copy(字典)
temp['宁夏'] = '银川'
print(temp, 字典, id(temp), id(字典), sep='n')
temp['一线'].append('北京')
print(temp, 字典, id(temp), id(字典), sep='n')
--------------------------------
{'山西': '太原', '河北': '石家庄', '河南': '郑州', '山东': '济南', '吉林': '长春', '一线': []}
// 对字典自身(非可变对象)修改是独立的
{'山西': '太原', '河北': '石家庄', '河南': '郑州', '山东': '济南', '吉林': '长春', '一线': [], '宁夏': '银川'}
{'山西': '太原', '河北': '石家庄', '河南': '郑州', '山东': '济南', '吉林': '长春', '一线': []}
// 地址是独立的
2173107763712
2173111155520
// 字典中可变对象一线的改变 同时作用与源对象与拷贝对象
{'山西': '太原', '河北': '石家庄', '河南': '郑州', '山东': '济南', '吉林': '长春', '一线': ['北京'], '宁夏': '银川'}
{'山西': '太原', '河北': '石家庄', '河南': '郑州', '山东': '济南', '吉林': '长春', '一线': ['北京']}
2173107763712
2173111155520
总结:浅拷贝对象中的可变对象是共享引用
2.2 deep copy:
在Python中,你可以使用copy
模块的deepcopy()
函数来实现深拷贝。这个对象及其所有子对象都是完全独立的,与原始对象没有任何共享。
示例:
代码语言:javascript复制deep = copy.deepcopy(字典)
print(deep)
字典['一线'].append('上海')
deep['一线'].append('深圳')
print(f'字典: {字典} ndeep: {deep} n id(字典)={id(字典)} id(deep)={id(deep)}')
--------------------------------
{'山西': '太原', '河北': '石家庄', '河南': '郑州', '山东': '济南', '吉林': '长春', '一线': ['北京']}
字典: {'山西': '太原', '河北': '石家庄', '河南': '郑州', '山东': '济南', '吉林': '长春', '一线': ['北京', '上海']}
deep: {'山西': '太原', '河北': '石家庄', '河南': '郑州', '山东': '济南', '吉林': '长春', '一线': ['北京', '深圳']}
id(字典)=2334986648384 id(deep)=2334986646784
总结:深拷贝对象中的可变对象是独立引用