Python函数中列表追加行为不符合预期问题咨询
Python可变默认参数的陷阱:为什么list1会被意外修改?
先还原你的代码和问题场景:
你的代码:
def extendList(val, list=[] ): list.append(val) return list list1 = extendList(10) print "value of list1 before = %s" % list1 list2 = extendList(123,[]) list3 = extendList('a') print "value of list1 after = %s" % list1
你预期的输出:
value of list1 before = [10] value of list1 after = [10]
实际得到的输出:
value of list1 before = [10] value of list1 after = [10, 'a']
问题根源:Python默认参数的初始化时机
这是Python里一个非常经典的坑——默认参数是在函数定义的时候就完成初始化,而不是每次调用函数时重新创建。对于列表、字典这种可变对象来说,这个初始化后的对象会被所有不传入该参数的函数调用共享。
具体到你的代码流程:
- 当你写下
def extendList(val, list=[])时,Python就已经创建了一个空列表对象,这个对象会一直绑定在函数的默认参数上,不会因为函数调用而重新生成。 - 第一次调用
extendList(10):使用这个默认的空列表,执行append(10)后列表变成[10],list1引用的就是这个列表对象。 - 第二次调用
extendList(123, []):你手动传入了一个全新的空列表,这次操作的是这个新列表,和默认列表完全无关,list2最终是[123]。 - 第三次调用
extendList('a'):再次复用了函数定义时创建的那个默认列表(也就是list1引用的那个),执行append('a')后,这个列表变成[10, 'a'],所以list1的值自然跟着改变了。
解决方案:避免用可变对象做默认参数
正确的写法是把默认参数设为None,然后在函数内部判断并初始化新的列表,这样每次调用如果不传list参数,都会生成一个全新的空列表:
def extendList(val, list=None): if list is None: list = [] list.append(val) return list
再运行你的测试代码,list1就不会被list3的调用影响,输出会完全符合你的预期。
内容的提问来源于stack exchange,提问作者Anoop Sharma
相关产品推荐
相关产品推荐

