这里的新手问题。我很困惑为什么,只有在某些语法下,当分配给它的另一个列表得到更新时,列表才会自动更新。例如,
如果我们将'a'分配给'b'并更新'b','a'仍然不受影响:
>>> b = [1,1,0]
>>> a = b
a = [1,1,0]
>>> b = [0,0,0]
a = [1,1,0]
但是,如果我们将最后一次更新命令重写为:
>>> b[:2] = [0]*2
a = [0,0,0]
为什么?
答案 0 :(得分:5)
因为a
和b
是对象的引用。当你写:
a = b
然后a
和b
引用相同的对象,因此当您在b
上对其进行修改时,a
也会发生变化。如果他们指向指针(并且在引擎盖下),那么它们将指向同一个对象。
当你写:
b[:2] = [0, 0] # [0] * 2
您正在修改列表,因此更改将反映在a
中。
相反,当你写:
b = [0,0,0]
b
将引用一个新的不同列表,更改不会反映在a
中。
答案 1 :(得分:2)
执行b = [0,0,0]
之类的简单分配时,您在内存中创建新列表对象,并将b
更改为指向 new 列表对象。这与a
无关,可能指向某个其他位置(包括b
用于指向的位置,如此处所示)。
当您分配到b[:2] = [0]*2
中的切片时,您正在进行就地修改,因此可以通过指向b
列表的任何指针看到更改。在这种情况下,这也意味着a
。
例如,考虑稍微修改您的第一个代码段:
>>> b = [1,1,0]
>>> a = b
>>> b[:] = [0,0,0]
>>>
>>> a
[0, 0, 0]
>>> b
[0, 0, 0]
请注意,现在a
和 b
已修改,因为分配到b[:]
会修改b
指向的列表,并且,由于a
指向相同的列表,我们也可以通过a
看到更改。同样,这与您的第一个代码段相反,其中b
被重定向为完全指向一个新对象。