分清楚是传的是值还是引用
Python在对列表的初始化过程中会经常用到列表的乘法生成一个含有重复元素的列表,例如 l = [0]*10
但是如果列表中包含有可变数据类型(列表、字典)的话使用*
操作符便会有很大问题。 *
操作符在实现上是复制了值的引用,而不是创建了新的对象。如果其中一个数据改变,其他的也会跟着改变。 如下代码:
m = 2
n = 3
dp = [[0 for _ in range(n+1)] for _ in range(m+1)]
dp2 = [[0] * (n + 1)] * (m + 1)
dp2[1][1] = 1
dp[1][1] = 1
print(dp)
print(dp2)
在pythontutor
中可视化代码运行过程,可以看出使用dp2中的使用*
操作符生成的列表中的3个元素都指向的同一个list
。而使用列表生成式生成的二维列表指向的都是不同的list
。 故python在初始化列表中尽量要使用列表生成器,而尽量少使用列表乘法。 参考链接: - 小心python的list乘法