Python大杂烩5:值和引用所引起的动态修改list值问题

1.场景

有一天,同事问我:“我在动态改变一个list值的时候总是不遂人愿,你帮我看看是哪里出了问题?”
她的代码是这么写的:

#fromTongshi.py
#2020.06.07
language = ["Python",0]
scores = [75,80,90]

result = []
for score in scores:
    language[-1] = score
    result.append(language)
print(result)

她想象的结果是这样的:

[['Python', 75], ['Python', 80], ['Python', 90]]

实际上结果是这样的:

[['Python', 90], ['Python', 90], ['Python', 90]]

问题出在哪里呢?

2.值和引用

在Python里,数据类型分为2种,可变类型不可变类型
可变类型:字典(dict), 集合(set), 列表(list)
不可变类型:整型(int), 字符串(string), 浮点型(float), 元组(tuple)

可变类型的对象在被调用时传递的是该对象的值。
不可变类型的对象在被调用时传递的是该对象的位于内存中的数据的引用。

来解释一下同事的难题:
language是一个可变类型的对象。在result.append(language)以后,language将它的引用传递给了result
在第1次append以后,result有了1个language的引用,此时result=[language的引用],而此时language的引用指向的数据是['Python', 75]
在第2次append以后,result有了2个language的引用,此时result=[language的引用, language的引用],而此时language的引用指向的数据是['Python', 80]
在第3次append以后,result有了3个language的引用,此时result=[language的引用, language的引用,language的引用],而此时language的引用指向的数据是['Python', 90]

3.曲线救国

如果真的想实现这个功能应该怎么做呢?
我们可以利用一个中间变量,来保证每次循环时都重新生成这个变量。
如:

language = ["Python",0]
scores = [75,80,90]

result = []
for score in scores:
    temp = language[:-1]
    temp.append(score)
    result.append(temp)
print(result)

你可能感兴趣的:(Python大杂烩5:值和引用所引起的动态修改list值问题)