前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[PYTHON] 小坑--神奇的引用!

[PYTHON] 小坑--神奇的引用!

原创
作者头像
大大刺猬
发布2024-11-08 15:38:00
900
发布2024-11-08 15:38:00

水一篇, 起因是写aes的时候, 不是要4*4的list做各种操作么, 为了省事, 就写成[[0]*4]*4了, 然后就死活不行...

现象

在python中, 我们经常使用 * 来创建一个指定长度的list, 比如 [0]*4 就得到一个[0, 0, 0, 0] ,非常的方便. 但使用这种方法创建二维数组时, 却有意外了.

不好描述, 直接看代码吧

代码语言:python
代码运行次数: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任一元素赋值时, 有趣的现象发生了.

代码语言:python
代码运行次数:0
复制
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

我们可以再做个小实验, 验证一下

代码语言:python
代码运行次数:0
复制
L1 = [1,2,3]
L2 = L1
L1[0] = 666
print('L1的值:',L1) 
print('L2的值:',L2)

虽然我们修改的是L1的值, 但我们查看L2, 却发现L2的值也变化了, 这就是引用.

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 现象
  • 分析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档