Python函数意外修改传入的列表输入变量,该如何预防和修复?
问题原因
Python中的列表属于可变对象,作为参数传入函数时传递的是内存引用而非独立副本,也就是说函数内的形参D和外部的实参DD指向的是内存里的同一个列表对象。
你在函数内部修改D中子元素的操作,本质就是直接修改原列表DD的内容,这一行为和return语句是否存在没有任何关系。另外代码中n = D[y-1]拿到的是子列表的引用,修改n[x-1]时就已经完成了对原列表的改动,后续的D[y-1] = n属于冗余操作,有无都不影响结果。
解决方法
如果要实现「不修改原列表,仅返回修改后的新列表」的预期功能,需要在修改操作前对传入的嵌套列表做拷贝,生成独立的新对象操作。因为是嵌套列表结构,需要用深拷贝保证所有层级的子列表都独立,修改后的代码如下:
import copy DD = [] for i in range(10): DD += [[" "," "," "," "," "," "," "," "," "," "]] def WD(x, y, D, V): # x=子列表索引 y=列表索引 D=传入列表 V=替换值 # 深拷贝传入的列表,生成完全独立的新对象 new_D = copy.deepcopy(D) n = new_D[y-1] n[x-1] = V new_D[y-1] = n return new_D # 接收函数返回的新列表,原DD不会被修改 new_DD = WD(5, 5, DD, "##") print("原列表DD:") print(DD) print("修改后的新列表new_DD:") print(new_DD)
如果你的列表固定只有两层嵌套,也可以手动实现双层拷贝,性能比通用的深拷贝更高:new_D = [sub_list.copy() for sub_list in D]
内容的提问来源于stack exchange,提问作者Joseph Montrose
相关产品推荐
相关产品推荐

