水一篇, 起因是写aes的时候, 不是要4*4的list做各种操作么, 为了省事, 就写成[[0]*4]*4了, 然后就死活不行...
在python中, 我们经常使用 * 来创建一个指定长度的list, 比如 [0]*4
就得到一个[0, 0, 0, 0]
,非常的方便. 但使用这种方法创建二维数组时, 却有意外了.
不好描述, 直接看代码吧
s1 = [[0]*4]*4
s2 = [[0] * 4 for _ in range(4)]
print('s1类型:',type(s1),'\ns1值:',s1)
print('s2类型:',type(s2),'\ns2值:',s2)
print('s1 ?= s2 :',s1==s2)
执行上述代码, 我们将看到 s1和s2类型一样, 值也一样.
那么s1和s2真的就一样了么?
其实并不是. 当我们给s1的子list任一元素赋值时, 有趣的现象发生了.
s1 = [[0]*4]*4
s2 = [[0] * 4 for _ in range(4)]
s1[1][1] = 1
s2[1][1] = 1
print('s1值为:',s1)
print('s2值为:',s2)
我们发现s1的每个子list的第二个元素都变成了1
修改1个'变量'的值, 其它'变量'值也发生了变化, 基本上马上就能猜到是引用的问题. 但排查问题的时候,可不会先想到这写法有啥问题. 毕竟1维list我们就是这么写的. 那二维理论上也差不多啊.
能这样理解就表示我基础知识不牢固了. 当变量指向不可变对象时, 会创建一个新的对象(怕你修改不可变变量), 当变量指向一个可变对象时, 就是创建一个引用了(节省资源?).
1. 当创建一个包含整数的列表时,Python 会为每个整数创建一个独立的对象
2. 当创建一个包含列表的列表时,Python 只会创建一个包含对同一个列表对象的引用的列表
使用 | 解释 |
---|---|
[0]*4 | 0是不可变对象,故每个元素都是新的对象 |
[[0]*4]*4 | 1. 先创建4个新对象组成一个list. 2.list是可变对象,故再创建4个(其实是3个)引用组成list.list |
我们可以再做个小实验, 验证一下
L1 = [1,2,3]
L2 = L1
L1[0] = 666
print('L1的值:',L1)
print('L2的值:',L2)
虽然我们修改的是L1的值, 但我们查看L2, 却发现L2的值也变化了, 这就是引用.
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。