Python3.8中函数修改列表导致同引用外部变量变更如何解决
问题本质原因
Python的列表属于可变数据类型,使用=直接赋值时,并不会复制生成新的列表对象,只是为内存中已存在的同一个列表新增了一个变量别名。也就是说list_1和list_2指向的是完全相同的内存地址,修改其中任意一个变量关联的列表内容,另一个变量访问到的也会是修改后的数据。
同时Python函数传参采用的是传对象引用的逻辑,你把list_1传入函数后,函数内部拿到的也是同一个列表对象的引用,执行append(4)操作时直接修改了内存里的原列表,因此两个变量打印时都会显示追加元素后的结果。
实现预期效果的方案
你的需求是保留list_2为初始的[1,2,3],只需要在给list_2赋值时,创建原列表的独立副本即可,常用的实现方式有3种:
- 切片拷贝:写法最简洁,全切片操作会默认生成新的列表对象
list_2 = list_1[:] - 构造方法拷贝:调用list类型的构造函数,基于原列表生成全新实例
list_2 = list(list_1) - copy模块拷贝:如果列表中嵌套了其他可变对象(比如子列表、字典),前两种浅拷贝方式无法完全独立数据,需要用深拷贝;你当前的单层列表场景用浅拷贝即可满足需求
import copy list_2 = copy.copy(list_1) # 浅拷贝,和前两种效果一致 # list_2 = copy.deepcopy(list_1) # 嵌套可变结构时使用深拷贝
修正后的完整代码
def fun(list_1): list_1.append(4) list_1 = [1,2,3] list_2 = list_1[:] # 此处创建独立副本,不再和list_1指向同一份数据 fun(list_1) print(list_1) # 输出 [1, 2, 3, 4] print(list_2) # 输出 [1, 2, 3],符合预期
补充说明:如果你不希望函数修改外部传入的原始列表,也可以在函数内部第一行先创建传入列表的副本,后续操作都基于副本进行,不会影响外部的原始数据。
内容的提问来源于stack exchange,提问作者Basavkumar Patil
相关产品推荐
相关产品推荐

