文章目录
引言:列表的注意事项
1 特别注意:列表的切片赋值操作就是 — 浅拷贝
ls = [1,[2,3],4,5]
a = ls[1:3] # [[2, 3], 4] 将列表切片进行赋值给变量a。本质上就是浅拷贝
a[1] = 100
print(a) # [[2, 3], 100]
print(ls) # [1, [2, 3], 4, 5] 浅拷贝修改顶层不影响原列表
a[0][0] = 200
print(ls) # [1, [200, 3], 4, 5] 浅拷贝修改内层可变数据类型会影响原列表
【注】:注意和这种修改操作区分开,你要浅拷贝至少要赋值个一个变量吧!
ls = [1,[2,3],4,5]
ls[0] = 10
print(ls) # [10, [2, 3], 4, 5]
2 赋值、切片修改、切片赋值
一定要看完这篇博客内存模型更好理解。
(1)整个列表赋值给另一个变量 — lst2 = lst
lst = [1, 2, 3]
lst2 = lst # 这种整个完整列表赋值给另一个变量绑定的是引用,你变我也变,一个被修改了,另一个也被会被修改
lst2[0] = 4
print(lst) # [4, 2, 3] 原始列表也被修改了
(2)切片赋值 = 浅拷贝 — lst2 = lst[1:]
将切片赋值给一个新的变量 = 浅拷贝。修改最顶层数据(可变不可变数据都一样)不会影响原始列表,但是修改顶层可变数据内部元素影响原始列表。
lst = [1, 2, 3,[4,5,6]]
lst2 = lst[1:] # lst2 = [2, 3, [4, 5, 6]] 切片赋值给新的变量,新变量的id和原变量的id不同,相当于浅拷贝
lst2[2] = 100 # 修改lst2的顶层元素,不会影响原变量
print(lst2) # [2, 3, 100]
print(lst) # [1, 2, 3, [4, 5, 6]]
【注】:浅拷贝创建一个新的列表对象,但新的列表中的元素是对原始列表中元素的引用。因此,浅拷贝后的列表本质上是与原列表共享数据的视图。如果原列表中的元素是可变对象,修改其中一个列表中的对象会影响到另一个列表,因为它们指向相同的内存地址。根据这个原来画出内存模型,一步一步分析能理解了。
(3)切片修改 — lst[0] = 100
需要注意的是切片修改没有绑定新变量,还是在原来的引用上进行操作,一定要和切片赋值区分开来。
lst[0] = 100
一、list的深拷贝与浅拷贝
在 Python 中,列表的浅拷贝和深拷贝是两种不同的复制方法,它们在数据的引用和内存管理方面有显著差异。理解这两种拷贝方式对于避免不必要的副作用和确保数据独立性至关重要。
1 浅拷贝(Shallow Copy)
浅拷贝创建一个新的列表对象,但新的列表中的元素是对原始列表中元素的引用。因此,浅拷贝后的列表本质上是与原列表共享数据的视图。如果原列表中的元素是可变对象,修改其中一个列表中的对象会影响到另一个列表,因为它们指向相同的内存地址。
浅拷贝的方法
-
使用
list()
函数:original_list = [1, 2, [3, 4]] shallow_copy = list(original_list)
-
使用切片
[:]
:以后记住列表切片本质上就是浅拷贝original_list = [1, 2, [3, 4]] shallow_copy = original_list[:]
-
使用
copy
模块的copy()
函数:import copy original_list = [1, 2, [3, 4]] shallow_copy = copy.copy(original_list)
浅拷贝的效果
浅拷贝后的列表 shallow_copy
和原列表 original_list
共享内部的可变对象,如嵌套列表。这意味着对这些共享的可变对象的修改会在两个列表中都反映出来。
import copy
original_list = [1, 2, [3, 4]]
shallow_copy = copy.copy(original_list)
# 修改原列表中的可变对象
original_list[2][0] = 10
print("原列表:", original_list) # 输出: 原列表: [1, 2, [10, 4]]
print("浅拷贝列表:", shallow_copy) # 输出: 浅拷贝列表: [1, 2, [10, 4]],嵌套列表被修改
然而,顶层的元素是独立的,修改其中的不可变元素或重新分配元素不会影响另一个列表:
original_list[0] = 100
print("原列表:", original_list) # 输出: 原列表: [100, 2, [10, 4]]
print("浅拷贝列表:", shallow_copy) # 输出: 浅拷贝列表: [1, 2, [10, 4]],顶层元素不受影响
2 深拷贝(Deep Copy)
深拷贝则创建一个新的列表对象,并且递归地复制原列表中所有的元素及其子元素。这样,深拷贝后的列表和原列表完全独立,修改深拷贝中的任何元素不会影响到原列表,反之亦然。
深拷贝的方法
- 使用
copy
模块的deepcopy()
函数:import copy original_list = [1, 2, [3, 4]] deep_copy = copy.deepcopy(original_list)
深拷贝的效果
深拷贝后,deep_copy
和 original_list
是完全独立的,修改一个列表中的任意元素都不会影响到另一个列表。
import copy
original_list = [1, 2, [3, 4