Python函数中List形参修改实参的成因与防御策略
本文解析Python中List作为函数形参时,因传递引用导致实参被意外修改的现象。通过对比可变与不可变对象的传递机制,指出直接修改形参会影响原始数据。解决方案包括在函数内部使用copy()或切片[:]创建副本,确保原始数据完整性。
摘要与问题描述
摘要
当把列表传入函数后,若函数内部对参数进行修改,外部实参会同步改变。本文将分析这一现象的具体表现、底层原因以及有效的规避方法。
代码示例与现象
代码示例
def fun(inner_lst):
inner_lst.pop()
lst = [1,2,3,4,5,6,7]
fun(lst)
print(lst)
fun(lst)
print(lst)
fun(lst)
print(lst)
fun(lst)
print(lst)
fun(lst)
print(lst)

从运行结果可以看出,
尽管代码中修改的是函数内部的变量inner_lst,但外部的原始列表lst也随之发生了改变。
因此,若将列表传入函数并执行,可能会破坏原始数据,这通常并非开发者所期望的结果。
底层原因分析
原因分析
首先解释上述现象产生的根本原因。
在Python中,数据分为两种类型:mutable(可变)和immutable(不可变)。
list和dict属于mutable类型;
int、string、float和tuple属于immutable类型。
在函数参数传递过程中:
对于immutable对象,传递的是值的副本;
对于mutable对象,传递的是对象的引用(指针)。
因此,当把lst传入fun()函数时,实际上是将lst的引用传递给了inner_lst变量。
所以,对inner_lst的修改会直接反映在lst上,导致其值发生变化。
解决方案与补充说明
解决方法
如果传入函数的形参是list变量,建议先进行拷贝,后续操作在副本上进行,从而避免破坏原始数据。
例如:
def fun(inner_lst):
lst_copy = inner_lst.copy()
lst_copy.pop()
print("lst_copy = ",lst_copy)
lst = [1,2,3,4,5,6,7]
fun(lst)
print("lst = ",lst)

补充知识:Python函数参数List形参改变实参问题
在学习Python排序算法时,发现自定义排序函数会改变实参中的原始List,影响后续对比。经查询和学习,总结如下:
若List中某一项的值被修改,实参会随之改变。
若对List整体重新赋值,则不会改变实参。
原因在于形参和实参这两个标签指向的是同一块内存列表。修改其中一个,另一个也会跟着改变。
解决方法如下,可在参数处理中加入:
在函数内部复制一个List,在新的List中进行排序操作。
def selectionSort(xx):
x=xx[:]
i = 0
while i < len(x) - 1:
j = i + 1
minindex = i
while j < len(x):
if x[minindex] > x[j]:
minindex = j
j += 1
x[minindex], x[i] = x[i], x[minindex]
i += 1
return x
以上关于在Python中防止List作函数形参被实参修改的实现方法,希望能为大家提供参考。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













