鉴于python中的所有内容都是通过引用,我确实理解下面的代码中发生了什么:
a = ['one']*3 // a = ['one', 'one', 'one']
b = [a]*3 // b = [['one', 'one', 'one'], ['one', 'one', 'one'], ['one', 'one', 'one']]
b[1][2] = 'two'
现在,b是
[['one', 'one', 'two'], ['one', 'one', 'two'], ['one', 'one', 'two']]
因为我们将b
引用了a
引用的相同对象的三倍,重新分配任何一个组件,所以在三个位置都会看到更改。
但是,为什么同样的事情发生在
a = [['one']]*3 // a = [['one'], ['one'], ['one']]
a[1] = ['two']
不会生成a = ['two', 'two', 'two']
,而只会生成[['one'], ['two'], ['one']
,好像现在有三个不同的对象指向。
我在这里错过了一些逻辑吗?
提前致谢, NIKHIL
答案 0 :(得分:3)
您没有更改a[1]
的内容,而是将其重新绑定以指向单独的数组。这对a[0]
和a[2]
无效。
请尝试以下方法:
In [4]: a = [['one']]*3
In [5]: a[1][0] = 'two'
In [6]: a
Out[6]: [['two'], ['two'], ['two']]
答案 1 :(得分:1)
我发现理解引用如何工作的最好方法是在Python Tutor通过模拟器运行它们(单击该链接将运行上面的示例)。这使情况非常清楚。这也值得一读this article。
答案 2 :(得分:1)
要记住的一件重要事情是,对象具有存在性和独立于指向它们的名称的身份;并且x = y
不意味着“将x
指向的对象的值更改为y
指向的内容”。这意味着“将x
指向y
指向的内容”。
使用id
可能有助于澄清正在发生的事情:
>>> a = [['one']]*3
>>> (id(a[0]), id(a[1]), id(a[2]))
(140193404836320, 140193404836320, 140193404836320)
>>> a[1] = ['two']
>>> (id(a[0]), id(a[1]), id(a[2]))
(140193404836320, 140193368088088, 140193404836320)
最初,a[0]
,a[1]
和a[2]
都是同一个对象,正如人们所期望的那样:
+------+------+------+ a -->| | | | +------+------+------+ \ | / | | | v v v +---------+ | ['one'] | +---------+
然后a[1] = ['two']
使a[1]
指向一个新对象:
+------+------+------+ a -->| | | | +------+------+------+ | | | | | | | | | | v | | +---------+ | | | ['two'] | | | +---------+ | | | | +---------+ | \> | ['one'] |</ +---------+
请注意,该图表已经过简化,以显示要点,['one']
和['two']
不是图中显示的简单值。