奇怪的[:]

Getdone 2016-04-27 09:21:26
在Python 3.5中碰到,
d=[[0]*3]*3
md=[[0,0,0],[0,0,0],[0,0,0]]
d= =md得到True。

但是
d[0][:]=[1,2,3]
得到
d=[[1, 2, 3], [1, 2, 3], [1, 2, 3]]


md[0][:]=[1,2,3]
得到
[[1, 2, 3], [0, 0, 0], [0, 0, 0]]
...全文
122 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Getdone 2016-04-28
  • 打赏
  • 举报
回复
理解了,应该是如下图,谢谢各位!

0矩阵采用*号和直接书写生成的存储有区别。
且d[0][:]=[1,2,3],将S2地址中存储的指针全部更换,分别指向数字对象1、2、3。
而d[0]=[1,2,3]则将d地址中列表第1项更换。

Getdone 2016-04-27
  • 打赏
  • 举报
回复
引用 1 楼 suiziugo 的回复:
d[0][:]=[1,2,3] ——> d = [1,2,3]*3
d和md到底是否相等呢?谢谢!
混沌鳄鱼 2016-04-27
  • 打赏
  • 举报
回复
楼主碰到python最常见的一个坑了 d=[[0]*3]*3这个写法有问题。 这样相当于 a = [0,0.0] [a, a, a] a 这个相同的list被引用了三次而已。 最规矩的写法是 d = [[0 for j in range(3) ]for i in range(3)] 高效且正确的写法是 d = [ [0]*3 for i in range(3)] 因为数值0是不可变对象,[0]* 这样写是没有问题的。
ForestDB 2016-04-27
  • 打赏
  • 举报
回复
4L推荐的内容不错,也给出了比较易懂的解释,这其实就是个深浅copy的问题。 推荐一个内置函数id(),具体的用法和含义自己去看文档。

>>> d = [[0] * 3] * 3
>>> id(d[0])
4299827464
>>> id(d[1])
4299827464
>>> id(d[2])
4299827464
>>> md = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> id(md[0])
4299826888
>>> id(md[1])
4299787656
>>> id(md[2])
4299827392
>>> 
上面这段能看明白,就知道d[0],d[1]和d[2]其实是同一个对象(浅copy), 所以d[0][:]=[1,2,3]改第0个就相当于3个对象都被修改了; 而md[0],md[1],md[2]是三个不同的对象, md[0][:]=[1,2,3]改第0个就只改第0个对象了。 那obj1 == obj2的含义呢? 这里的==,会考察两个方面的含义: id(obj1) == id(obj2),两个对象的id都相同,其实是同一个对象,那它们自然“相等”; id(obj1) != id(obj2),但是它们的“内容”相等; 显然,初始的d和md就是两个“不同”的对象,因为它们的id肯定不一样,但是它们的“内容”相等,所以说它们相等,是说的过去的。 最后,d = [[0] * 3] * 3,为什么会是浅copy,而md就不是呢? 还是看文档:https://docs.python.org/2.7/library/stdtypes.html#sequence-types-str-unicode-list-tuple-bytearray-buffer-xrange 这里有个seq对象的operator表,里面有个note 2,解释了这个问题,解释中还有个FAQ,https://docs.python.org/2.7/faq/programming.html#faq-multidimensional-list,可以进一步去看看。 =================================== http://python.usyiyi.cn/ Volunteers WANTED
suiziugo 2016-04-27
  • 打赏
  • 举报
回复
d[0][:]=[1,2,3] ——> d = [1,2,3]*3
竹聿Simon 2016-04-27
  • 打赏
  • 举报
回复
这里的问题并不在[:],而是python语言赋值的内在机制问题。 建议看看这篇博文:http://my.oschina.net/leejun2005/blog/145911 简单的说,通过d=[[0]*3]*3方式得到的d,其中的d[0]、d[1]、d[2]都指向同一个[0, 0, 0];而通过md=[[0,0,0],[0,0,0],[0,0,0]],其中的三个元素分别指向3个不同的[0, 0, 0]。 另外在这里,虽然d[0] = d[0][:],但是d[0]= [1, 2, 3] 与d[0][:] = [1, 2, 3]的含义却并相同,所以操作后d的结果也会不同,具体可以做实验查看。 这个比较难说清楚,建议结合上面那篇博文仔细体会。
suiziugo 2016-04-27
  • 打赏
  • 举报
回复
是相等的。 [0]*3 == [0,0,0] [[0]*3] == [[0, 0, 0]] [[0]*3]*3 == [[0,0,0],[0,0,0],[0,0,0]]

37,737

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • WuKongSecurity@BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧