作者uranusjr (←这人是超级笨蛋)
看板Python
标题Re: [问题] 关於list一问
时间Mon Mar 12 12:29:36 2012
※ 引述《latefall (惊起却回头)》之铭言:
: 最近初学python遇到一个list的问题
: 想求板上大大解答
: 我是用python 2.6.5在ubuntu上跑
: 後来在OS X上用python2跑也有一样的问题
: 如果我写
: x=[0,0]
: y=[0,0,0]
: for i in range(3):
: x[1]=i
: y[i]=x
: print y
: 输出是:
: [[0, 2], [0, 2], [0, 2]]
: 如果把y[i]=x那一行改成(其他保持不变)
: y[i]=[x[n] for n in range(2)]
: 输出变成:
: [[0, 0], [0, 1], [0, 2]]
: 我以为这两个写法是等价的?
: 是我有误解还是这是bug呢?
: 感谢解答
第一种的流程:
步骤 x 值 y 值
===================================================
把 x[1] 设成 0 [0, 0] [0, 0, 0]
把 y[0] 设成 x [0, 0] [[0, 0], 0, 0]
把 x[1] 设成 1 [0, 1] [[0, 1], 0, 0]
把 y[1] 设成 x [0, 1] [[0, 1], [0, 1], 0]
把 x[1] 设成 2 [0, 2] [[0, 2], [0, 2], 0]
把 y[2] 设成 x [0, 2] [[0, 2], [0, 2], [0, 2]]
关键在於 Python 的变数和 C(和其它类似语言)中变数的概念并不一样
在 Python 中, 所有的变数都是参考, 而不是容器
所以例如 y = x 这种述句的作用是「把 y 指向 x 的内容」
当你改变 x 的内容时, y 的内容(也就是 x 的内容)会一起改变
因为 x 和 y 是指向同一个东西, 而非同样值的两个独立物件
至於第二种, 因为 list comprehension 的结果是生成一个新物件
所以在这个作法中 y[0] y[1] 和 y[2] 都分别指向不同的物件
与第一种作法并不等价
--
「我最想要的同伴嘛,首先是要笑口常开,其次是我们能永远不会发生误会。
如果这些都能办到的话,嗯,如果他是世界上第一流的桥手,也还不错。」
-- 班尼多‧加罗素,前义大利蓝队成员
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.32.81.146
1F:推 latefall:感谢! 03/12 17:16
2F:推 latefall:所以 我应该把python变数都当成c的指标来理解? 03/12 17:20
3F:推 latefall:好像只有list是指标 感谢! 03/12 17:39
4F:推 AstralBrain:所有变数都是指标 03/13 03:09
5F:推 darkgerm:第二个方法是做了深复制,才有你希望的结果 03/13 21:38
6F:推 latefall:感谢楼上几位 03/13 22:30
7F:推 mikapauli:所有变数都是指标,但是物件有可不可变的差别 03/14 02:29
8F:→ mikapauli:因此只有可变物件(如list)才有办法像C的指标那样使用 03/14 02:31
9F:推 mikapauli:不可变物件无法改变其值,只能靠"指标"的改变 03/14 02:41
10F:→ mikapauli:另外在Python中immutable<==>hashable,自定义物件例外 03/14 02:44