python序列的深拷贝和浅拷贝
- python中的不可变类型
列举:数值,字符串、元组、字节串
-
- 数值及字符串“可变”'的假象
num = 123 mystr = 'abc' print(id(num), num) print(id(mystr), mystr) num = 456 mystr = 'def' print('修改后...') print(id(num), num) print(id(mystr), mystr) # 结果: 140704113688128 123 1853358409744 abc 修改... 1853359869712 456 1853361326544 def
表面上是对变量的修改,其实质是重新建立了对象,将引用赋给了变量,原来的对象被系统回收。
- python中的可变类型
列举: 列表、字典、字节数组、对象
- 浅拷贝
浅拷贝只拷贝可变类型的引用,在拷贝后的对象中对可变类型的修改会影响到原对象。
有几种方式实现:
1. 完全切片操作
2. 利用系统函数list(), dict()
3. 利用copy模块的copy函数
ll = ['xiao', ['china', 32]] la = copy(ll) lb = copy(ll) print(id(ll), ll) print(id(la), la) print(id(lb), lb) print('change...') la[0] = 'zhang' la[1][0] = 'usa' la[1][1] = 40 print(id(ll), ll) print(id(la), la) print(id(lb), lb) # 结果: 3006259174856 ['xiao', ['china', 32]] 3006259174536 ['xiao', ['china', 32]] 3006259174600 ['xiao', ['china', 32]] change... 3006259174856 ['xiao', ['usa', 40]] 3006259174536 ['zhang', ['usa', 40]] 3006259174600 ['xiao', ['usa', 40]]
- 深拷贝
对比浅拷贝,深拷贝利用copy模块的deepcopy()函数会完全拷贝出独立的对象来。
ll = ['xiao', ['china', 32]] la = deepcopy(ll) lb = deepcopy(ll) print(id(ll), ll) print(id(la), la) print(id(lb), lb) print('change...') la[0] = 'zhang' la[1][0] = 'usa' la[1][1] = 40 lb[0] = 'wang' lb[1][0] = 'japan' lb[1][1] = 49 print(id(ll), ll) print(id(la), la) print(id(lb), lb) # 结果: 1957762145864 ['xiao', ['china', 32]] 1957762145544 ['xiao', ['china', 32]] 1957762145672 ['xiao', ['china', 32]] change... 1957762145864 ['xiao', ['china', 32]] 1957762145544 ['zhang', ['usa', 40]] 1957762145672 ['wang', ['japan', 49]]
- 意外发现
元组中的列表不可以修改吗?
tt = (12, 33, [44, 55, 66]) print(tt) # 修改 tt[2][0] = 0 print(tt) # 结果: (12, 33, [44, 55, 66]) (12, 33, [0, 55, 66]) ## 元组中的元素tt[2]不可更改为其他内容,单列表中的元素可以随意修改。
列表中的元组可以修改吗?
dd = [1, 2, 3, 4, (7, 8, 9)] print(dd) dd[4] = 0 print(dd) # 结果: [1, 2, 3, 4, (7, 8, 9)] [1, 2, 3, 4, 0] ## 列表中元组内容不可修改,但dd[4]的值可修改。