为何给列表加[:]修改副本不影响原列表?Python列表拷贝疑问
问题根源:列表的引用赋值
你写的areas_copy = areas并不是创建原列表的副本,而是让areas_copy和areas这两个变量指向内存中同一个列表对象。所以修改areas_copy的元素时,本质上是在修改那个共享的列表对象,原列表areas自然也会跟着变。
三种创建独立副本的方法原理
这三种方式本质都是创建原列表的浅拷贝——生成一个全新的列表对象,把原列表的元素逐个复制到新对象里,两个列表不再共享内存空间,修改其中一个不会影响另一个。
1. 切片操作 [:]
列表的切片语法areas[:]会返回一个包含原列表所有元素的新列表。这里的切片省略了起始和结束索引,默认取整个列表的元素,相当于把原列表的元素依次复制到新列表中,最终areas_copy指向这个新列表,和原列表完全独立。
2. list() 构造函数
list(areas)会以原列表为输入参数,内部遍历原列表的所有元素,将它们逐个添加到新创建的空列表中,最终返回这个新列表。和切片操作的效果完全一致,都是生成独立的列表副本。
3. copy() 方法
列表自带的copy()方法就是专门用于创建浅拷贝的,底层实现逻辑和切片、list()构造函数类似,都是生成全新的列表对象并复制原元素,只是写法更直观。
对比示例代码
错误写法(共享同一对象)
areas = [11.25, 18.0, 20.0, 10.75, 9.50] areas_copy = areas # 只是引用赋值,未创建副本 areas_copy[0] = 5.0 print(areas) # 输出 [5.0, 18.0, 20.0, 10.75, 9.50],原列表被修改
正确写法(创建独立副本)
areas = [11.25, 18.0, 20.0, 10.75, 9.50] # 方式1:切片[:] areas_copy1 = areas[:] areas_copy1[0] = 5.0 print(areas) # 输出 [11.25, 18.0, 20.0, 10.75, 9.50],原列表不变 # 方式2:list()构造函数 areas_copy2 = list(areas) areas_copy2[0] = 3.0 print(areas) # 输出 [11.25, 18.0, 20.0, 10.75, 9.50],原列表不变 # 方式3:copy()方法 areas_copy3 = areas.copy() areas_copy3[0] = 1.0 print(areas) # 输出 [11.25, 18.0, 20.0, 10.75, 9.50],原列表不变
注意:以上都是浅拷贝,如果原列表包含可变子对象(比如子列表、字典),浅拷贝会共享这些子对象。但你的例子里都是数值类型(不可变),所以完全适用。
内容的提问来源于stack exchange,提问作者S Yuri
相关产品推荐
相关产品推荐

