Python 可变/不可变/浅拷贝
本帖最后由 Free_num 于 2023-8-30 16:19 编辑可变/不可变/浅拷贝
'''
<font size="3" color="#ff8c00">可变类型</font>:数据可直接进行修改且id不变化---------->证明修改的是原值
<font color="#ff8c00" size="3">不可变类型</font>:值改变,id也变---------->原值不能被修改
二者可以通过ID来区分
可变类型:列表、字典、集合
不可变类型:字符串、元组、数据类型
元组被称为制度列表,即数据可以被查询,但是不能被修改,
'''
'''
li =
t = (1, 't', li)
print(f'修改元组中的列表前:{t}', id(t))
# 修改元组中的列表前:(1, 't', ) 1931246079296
li = 'Serena'
print(f'修改元组中的列表后:{t}', id(t))
# 修改元组中的列表后:(1, 't', ['Serena', 2]) 1931246079296
上面结果中,虽然元组数据发生了变化,但是id却未发生变化,那是因为元组中的列表是可变类型,列表的数据发生了变化,
但列表在元组中的地址的值没有发生变化
因此,元组的地址没有发生变化
'''
'''
<font size="3" color="#ff8c00">赋值:</font>如果是<u><i>可变类型数据</i></u>,赋值对象随着源对象的改变而改变,二者指向的是同一个内存地址
如果是<u><i>不可变类型数据</i></u>,没有影响
'''
<span style="background-color: mediumturquoise;"># 可变类型数据</span>
li1 = ]
li2 = li1
print(f'源列表修改前li1:{li1}', id(li1))
print(f'源列表修改前li2:{li2}', id(li2))
li1 = 's'
print(f'源列表修改后li1:{li1}', id(li1))
print(f'源列表修改后li2:{li2}', id(li2))
li2 = 123
print(f'li2列表修改后li1:{li1}', id(li1))
print(f'li2列表修改后li2:{li2}', id(li2))
'''
以上的id值均相同----->赋值是可变类型数据,内存地址是同一个,所以无论改变的是源对象还是赋值对象,id都一样
'''
<span style="background-color: mediumturquoise;"># 不可变类型数据</span>
a = 7
b = a
print(id(a),'\t', id(b)) # 2023961330096 2023961330096
# 对源对象进行修改
a = 's'
print(id(a), '\t', id(b)) # 2023962151920 2023961330096 ------> 没有影响
<span style="background-color: mediumturquoise;"><font size="4"># 深、浅拷贝,使用时需要导包 import copy</font></span>
'''
<font size="3" color="#ff8c00"> 浅拷贝:</font>创建一个新对象,引用的是源对象的子对象---------内层地址不会改变,外层数据地址改不改变看外层数据类型
使用:copy.copy()
'''
import copy
<span style="background-color: mediumturquoise;"><font size="3"># 外层可变,内层可变</font></span>
l =
l1 = copy.copy(l)
print('源对象外层数据地址:', l, id(l)) # 1589324513344
print('浅拷贝后的外层数据地址:', l1, id(l1)) # 1589324494400外层地址改变
print('--------- 内层 ----------')
print('源对象内层数据地址:', id(l)) # 1589324258144
print('浅拷贝后的内层数据地址:', id(l)) #1589324258144内层地址不变
print('-------------------')
l.append('¥')
print('外层修改后源对象:', l) #
print('外层修改后的浅拷贝:', l1) #
print('-------------------') # 外层内存地址不同,数据不会产生影响,外层数据是独立的
l.remove('q')
print('内层数据修改后源对象:', l) #
print('内层数据修改后的浅拷贝:', l1) #
print('-------------------')
<span style="background-color: wheat;">'''
引用的是源对象的子对象,所以内层内存地址相同,
由于内层是可变类型,可变类型数据发生变化时,id不变,因此当内层数据发生变化时,用的还是原来的内存地址,
故当内层发生变化时,浅拷贝对象的内层也发生相同的变化
'''</span>
<span style="background-color: mediumturquoise;"><font size="3"># 外层可变,内层不可变</font></span>
l2 =
l3 = copy.copy(l2)
print('源对象外层数据地址', l2, id(l2)) # 1589324494144
print('浅拷贝后的外层数据地址:', l3, id(l3)) # 1589324495104外层地址改变
print('--------- 内层 ----------')
print('源对象内层数据地址:', id(l2)) # 1589322737344
print('浅拷贝后的内层数据地址:', id(l2)) # 1589322737344 内层地址不变
print('-------------------')
l2.insert(1, 'e')
print('外层修改后源对象:', l2) #
print('外层修改后的浅拷贝:', l3) # 原因同上,外层数据资源独立
print('-------------------')
l2[-1] += (60,)
print('内层数据修改后源对象:', l2) #
print('内层数据修改后的浅拷贝:', l3) #
print('-------------------')
<span style="background-color: wheat;">'''
引用的是源对象的子对象,所以内层内存地址相同,
由于内层数据是不可变类型,当内层数据发生变化时,id发生变化,
而浅拷贝引用的是改变之前的内存空间,
故当内存数据发生改变时,浅拷贝的对象未发生变化
'''</span>
<span style="background-color: mediumturquoise;"><font size="3"># 外层不可变,内层可变</font></span>
l4 =
t = ('er', 4, l4)
t1 = copy.copy(t)
print('源对象外层数据地址', t, id(t)) # 1589324527488
print('浅拷贝后的外层数据地址', t1, id(t1)) # 1589324527488 外层地址未发生变化
print('--------- 内层 ----------')
print('源对象内层数据地址', id(l4)) # 1589324493440
print('浅拷贝后的内层数据地址', id(t1[-1])) # 1589324493440 内层地址不变
print('-------------------')
t += (90,)
print('外层数据修改后源对象:', t) # ('er', 4, , 90)
print('外层数据修改后的浅拷贝:', t1) # ('er', 4, )
print('-------------------')
l4.append('WE')
print('内层数据修改后源对象:', t) # ('er', 4, , 90)
print('内层数据修改后的浅拷贝:', t1) # ('er', 4, )
<font size="3" style="background-color: mediumturquoise;"># 外层不可变,内层不可变</font>
'''
这个就先不举例子啦
综上所述:
浅拷贝内层数据内存地址不会发生改变
外层数据是可变类型-----会改变
是不可变类型-----不会改变
'''
页:
[1]