鱼C论坛

 找回密码
 立即注册
查看: 2502|回复: 5

[已解决]列表乘法,一个有意思的现象

[复制链接]
发表于 2016-8-22 21:57:06 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 from_now 于 2016-8-22 21:59 编辑

今天对列表进行乘法时,发现一个有趣的现象。

快速生成一个有重复元素的list可以用*表示。如下面:
  1. >>> c=[1,2,3]*3
  2. >>> c
  3. [1, 2, 3, 1, 2, 3, 1, 2, 3]
复制代码

生成后的list就是一个普普通通的列表,没区别。可以调用list元素,对元素进行改写等。
  1. >>> c[1]
  2. 2
  3. >>> c[1]='list'
  4. >>> c
  5. [1, 'list', 3, 1, 2, 3, 1, 2, 3]
  6. >>>
复制代码


但是,如果对多维list进行乘法,结果一定要注意了。如下面:
  1. >>> d=[[1,2,3]]*3
  2. >>> d
  3. [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
  4. >>>
复制代码

上面用乘法生成了一个多维的list,看上去普普通通。可以调用里面元素。
  1. >>> d[1]
  2. [1, 2, 3]
  3. >>> d[0][2]
  4. 3
  5. >>>
复制代码

但是对此list里面的一个元素重新赋值,发现所有复制来的元素全跟着改变了。
  1. >>> d[1][1]='wa~~'
  2. >>> d
  3. [[1, 'wa~~', 3], [1, 'wa~~', 3], [1, 'wa~~', 3]]
复制代码

这是不是python为了简便,实际上没有在内存中创建这个由乘法生成list,内存中只
保留原先本体list,运算后的list是其复制,只要本体list变了,都跟着变了?
最佳答案
2016-8-23 10:09:49
本帖最后由 SixPy 于 2016-8-23 10:12 编辑

c=[1,2,3]*3 # 实际上是复制了3份 1、2、3 整数对象的指针
c[1]='list'   #  c[1]指针重新指向了 str对象,因为 整数是不可变对象,所以 其他 2 的值没变。

--------
d=[[1,2,3]]*3 # 实际是复制了 3份 同一个list对象的 指针。
d[1][1]='wa~~' # 改变 list元素的值,list是可变对象,所以,元素中的值变了,


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-8-23 09:48:14 | 显示全部楼层
you are right
  1. >>> arr = [[1, 2, 3]] * 3
  2. >>> arr
  3. [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
  4. >>> id(arr[0][1])
  5. 1600704992
  6. >>> id(arr[1][1])
  7. 1600704992
  8. >>> id(arr[2][1])
  9. 1600704992
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-8-23 10:09:49 | 显示全部楼层    本楼为最佳答案   
本帖最后由 SixPy 于 2016-8-23 10:12 编辑

c=[1,2,3]*3 # 实际上是复制了3份 1、2、3 整数对象的指针
c[1]='list'   #  c[1]指针重新指向了 str对象,因为 整数是不可变对象,所以 其他 2 的值没变。

--------
d=[[1,2,3]]*3 # 实际是复制了 3份 同一个list对象的 指针。
d[1][1]='wa~~' # 改变 list元素的值,list是可变对象,所以,元素中的值变了,


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

使用道具 举报

发表于 2016-8-23 10:11:08 | 显示全部楼层
不要用  C 的变量概念来套 python
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-8-23 10:19:34 | 显示全部楼层
正确的二维数组
  1. >>> d=[[1,2,3] for i in range(3)]
  2. >>> id(d[0])
  3. 27314256
  4. >>> id(d[1])
  5. 27314336
  6. >>> id(d[2])
  7. 27313656
  8. >>> d
  9. [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
  10. >>> d[1][1]=99
  11. >>> d
  12. [[1, 2, 3], [1, 99, 3], [1, 2, 3]]
  13. >>>
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-8-23 11:26:43 | 显示全部楼层
明白了
还是版主的这个方法好,直接用列表生成式,谢谢@SixPy
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-6-2 05:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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