为何Python中list.append()会重复添加同一内容?技术咨询
为什么
list.append()会重复添加相同内容? 嘿,这个问题其实是Python里对象引用机制的经典坑,我来给你掰扯清楚~
第一段代码的问题根源
先看你的第一段代码:
ret=['aaa'] def generateMessage(num): ret[0]=num return (ret) outputfile=[] for cnt in range(0,5): tmp=generateMessage(cnt) print("TMP is: ") print(tmp) outputfile.append(tmp) print("OutputFile is: ") print(outputfile)
这里的核心问题是:ret=['aaa']定义的是一个全局唯一的列表对象——整个程序运行期间,这个列表只有一份,所有对ret的操作都是在修改同一个列表。
具体流程是:
- 第一次循环
cnt=0:修改全局列表ret的第一个元素为0,返回这个列表的引用,append到outputfile; - 第二次循环
cnt=1:还是修改同一个全局列表的第一个元素为1,返回同一个引用,append到outputfile; - 以此类推,直到最后一次循环
cnt=4:把全局列表的元素改成4。
因为outputfile里的5个元素都是指向同一个全局列表的引用,所以最后打印时,所有元素都会显示成[4]——这不是append重复了,而是所有元素本来就是同一个东西。你看到的每次tmp打印不同,只是因为当时全局列表刚好被修改成了对应的值,但本质上都是同一个列表。
第二段代码为什么没问题?
再看第二段代码:
ret=[] def generateMessage(num): ret=num return (ret) outputfile=[] for cnt in range(0,5): tmp=generateMessage(cnt) outputfile.append(tmp)
这里的关键是:函数里的ret=num是局部变量,每次调用generateMessage时,都会创建一个新的局部变量(这里是整数,属于不可变类型),返回的是这个新数值的引用。
每次append到outputfile的都是不同的整数对象,自然不会出现所有元素都一样的情况,最后结果就是[0,1,2,3,4]。
怎么修复第一段代码?
给你两个简单的修复方案:
- 在函数内创建新列表(最推荐,避免全局变量带来的副作用):
# 去掉全局的ret定义 def generateMessage(num): ret = [num] # 每次调用都生成新的列表 return ret outputfile=[] for cnt in range(0,5): tmp=generateMessage(cnt) outputfile.append(tmp) print(outputfile) # 输出 [[0], [1], [2], [3], [4]]
- append时复制列表(如果必须保留全局列表的逻辑):
ret=['aaa'] def generateMessage(num): ret[0]=num return ret outputfile=[] for cnt in range(0,5): tmp=generateMessage(cnt) outputfile.append(tmp.copy()) # 复制一份新列表再append print(outputfile) # 输出 [[0], [1], [2], [3], [4]]
内容的提问来源于stack exchange,提问作者walle
相关产品推荐
相关产品推荐

