鱼C论坛

 找回密码
 立即注册
查看: 224|回复: 9

[已解决]关于列表的乘法的一个疑问

[复制链接]
发表于 2025-3-7 17:03:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
大家好,在学习视频,有一个问题我没理解,就是嵌套列表的乘法。
在代码:
A=[[0]*3]*3
A[0][0] is A[0][1]
结果是true
A[1][1] is A[1][2]
结果是true
把所有元素is两两一遍,结果都是true
A[1][1]=2
print(A)
输出是:[[0,2,0], [0,2,0], [0,2,0]].
为什么不是输出[[2,2,2],[2,2,2],[2,2,2]]


在代码:
A=[0]*3
A[0] is A[1]
结果是True
A[0]=3
print(A)
输出结果是【3,1,1】
为什么结果不是【3,3,3】呢
最佳答案
2025-3-8 11:28:22
本帖最后由 jackz007 于 2025-3-8 11:34 编辑

        关于 Python 的 is 运算符,首先要搞清楚,is 运算符比较的是什么,答案是对象的 id,就是说,当两个被比较对象的 id 值相同的时候,比较结果将是 True,这也意味着被比较的两个对象实际上是同一个对象。
         A = [[0] * 3] * 3
         将创建一个二维列表 :  [[0,0,0],[0,0,0],[0,0,0]]
         这个列表有如下特点:
1、A 有 3 个元素,A[0],A[1],A[2],这 3 个元素是通过同一个列表复制而成,所以,这三个元素互为镜像,也就是说,id(A[0])、id(A[1])、id(A[2]) 的值是完全相同的,我们知道,列表属于可变对象,是支持修改的,也就是说,修改列表内容不会造成其 id 值的改变。因此,我们会看到,修改 A[0]、A[1] 、A[2] 中的任何一个,其它两个会同步改变,道理很简单,因为它们本来就是同一个列表,所以,我们会看到:
A[1][1]=2
print(A)
输出是:[[0,2,0], [0,2,0], [0,2,0]]

2、A[0]、A[1]、A[2]  中的元素都是通过同一个常数 0 复制而成,所以,A[0]、A[1]、A[2] 这三个列表中的每一个元素 (0) 的 id 值都相同,因为它们也是同一个对象(0),所以:
A[0][0] is A[0][1]
结果是true
A[1][1] is A[1][2]
结果是true
把所有元素is两两一遍,结果都是true

对于代码 : A = [0] * 3
        根据前面的交代,is 操作都是 True,当执行 A[0] = 3 后,A[0] 被重新赋值成为另一个对象,与 A[1]、A[2] 脱离镜像关系,也就是说,重新赋值后,id(A[0]) 会改变,而 id(A[1]) 和 id(A[2]) 依然维持原来的数值,也就是说,赋值操作后,A[1]、A[2] 仍然是同一个对象,会不为所动,依然维持原样;
print(A)
输出是:[3,0,0]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2025-3-7 17:03:34 | 显示全部楼层
关于列表的乘法的解释

问题描述一:

对于代码:
A = [[1]] * 3
print(A)
输出的结果是 `[[1], [1], [1]]`。

这是因为 `[1]` 被复制了三次,所以表面上看上去列表 `A` 中有三个相同的 `[1]` 子列表。但实际上,这三个子列表是指向同一个对象,因此:
A[0] is A[1] # 结果是 True
A[1] is A[2] # 结果是 True

所有这些元素都是同一个对象。

问题描述二:

对于代码:
A = [1] * 3
print(A)
输出的结果是 `[1, 1, 1]`。

这是因为整数 `1` 被复制了三次,形成了一个长度为 3 的列表。如果我们再更新其中一个元素,例如 `A[0] = 3`,那么:
print(A)  # 结果是 [3, 1, 1]

这是因为整数是不可变对象,因此每个 `1` 在内存中是独立的。

总结来说,列表乘法 `[x] * n` 会复制元素 n 次。如果元素是可变对象(如列表),这些元素将指向同一个对象;如果元素是不可变对象(如整数),每个元素都是独立的。

希望这个解释可以帮助你理解列表乘法的行为。如果还有疑问,欢迎再提出来!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-3-7 19:43:05 | 显示全部楼层
FishC 发表于 2025-3-7 17:03
关于列表的乘法的解释

问题描述一:

谢谢回复,我仔细看看,想想
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-3-7 19:43:13 | 显示全部楼层
farm2046 发表于 2025-03-07 19:43
FishC 发表于 2025-3-7 17:03
关于列表的乘法的解释
...


不客气!如果有任何疑问,欢迎随时提出。继续学习,加油!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-3-8 11:28:22 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2025-3-8 11:34 编辑

        关于 Python 的 is 运算符,首先要搞清楚,is 运算符比较的是什么,答案是对象的 id,就是说,当两个被比较对象的 id 值相同的时候,比较结果将是 True,这也意味着被比较的两个对象实际上是同一个对象。
         A = [[0] * 3] * 3
         将创建一个二维列表 :  [[0,0,0],[0,0,0],[0,0,0]]
         这个列表有如下特点:
1、A 有 3 个元素,A[0],A[1],A[2],这 3 个元素是通过同一个列表复制而成,所以,这三个元素互为镜像,也就是说,id(A[0])、id(A[1])、id(A[2]) 的值是完全相同的,我们知道,列表属于可变对象,是支持修改的,也就是说,修改列表内容不会造成其 id 值的改变。因此,我们会看到,修改 A[0]、A[1] 、A[2] 中的任何一个,其它两个会同步改变,道理很简单,因为它们本来就是同一个列表,所以,我们会看到:
A[1][1]=2
print(A)
输出是:[[0,2,0], [0,2,0], [0,2,0]]

2、A[0]、A[1]、A[2]  中的元素都是通过同一个常数 0 复制而成,所以,A[0]、A[1]、A[2] 这三个列表中的每一个元素 (0) 的 id 值都相同,因为它们也是同一个对象(0),所以:
A[0][0] is A[0][1]
结果是true
A[1][1] is A[1][2]
结果是true
把所有元素is两两一遍,结果都是true

对于代码 : A = [0] * 3
        根据前面的交代,is 操作都是 True,当执行 A[0] = 3 后,A[0] 被重新赋值成为另一个对象,与 A[1]、A[2] 脱离镜像关系,也就是说,重新赋值后,id(A[0]) 会改变,而 id(A[1]) 和 id(A[2]) 依然维持原来的数值,也就是说,赋值操作后,A[1]、A[2] 仍然是同一个对象,会不为所动,依然维持原样;
print(A)
输出是:[3,0,0]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-3-9 15:31:00 | 显示全部楼层
因为int不是可变量,只是列表指向同一个内存地址而已。
A=[[[0]]*3]
A[1][1][:]=[2]
这下试试?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-3-9 17:57:26 | 显示全部楼层
player-none 发表于 2025-3-9 15:31
因为int不是可变量,只是列表指向同一个内存地址而已。

谢谢,增加了我的理解
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-3-9 20:29:44 | 显示全部楼层
farm2046 发表于 2025-3-9 17:57
谢谢,增加了我的理解

求最佳
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2025-3-10 14:26:29 | 显示全部楼层
这是Python列表的浅拷贝机制导致的。当用乘法创建嵌套列表时,外层列表存储的都是对同一个内层列表的引用。修改其中一个元素会联动修改所有引用。第一个案例中的[[0] 3]创建的是独立列表,但外层的 3复制了三次引用;第二个案例的[0]*3创建的是三个独立数字。建议使用列表推导式A=[[0]*3 for _ in range(3)]来创建独立嵌套列表。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-3-18 21:34:09 | 显示全部楼层
能不能这样理解,就是如果列表中的元素是通过*法复制而来的,且不是可变对象时,那么改变其中一个,其他不会改变,但是如果得到的元素是可变对象时,改变其中一个则肯定会改变其他的元素
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-2 02:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表