(我在示例中浪费了太多时间,@Konrad Rudolph 击败了我,我基本上和他说的是同样的话)
Python 在后台执行相当于 C 指针分配的操作,L1 将列表的地址保存在内存中,而 L2 只是复制了相同的地址。
您只需使用is
运算符即可签入代码。
>>> L1 is L2
True
但是,当使用切片时,必须创建一个新列表,因为它与原始列表不同,但是 python 是一个鬼鬼祟祟的混蛋,它不会复制所有内容,它只是复制对内部对象的引用。
这是一个更详细的示例:
>>> L1 = [1, [2, 3], 4]
>>> L2 = L1
>>> L2
[1, [2, 3], 4]
>>> L1[1] is L2[1]
True
好的,所以L1
保存了一个列表,里面有一个列表,你可以用字典、字符串或任何其他 python 对象替换它。请注意,is
运算符True
为列表中的列表返回。
然后,如果你使用切片技巧:
>>> L3 = L1[:2]
>>> L3
[1, [2, 3]]
>>> L3 is L1
False
>>> L3[1] is L2[1]
True
外部列表已更改,但内部的对象保持不变,这称为浅拷贝。事实上,相同的规则一直适用,如果我们在列表中向列表中添加一个新项目:
>>> L3[1].append(9)
>>> L3
[1, [2, 3, 9]]
>>> L1
[1, [2, 3, 9], 4]
(注意添加的 9) 列表里面的L1
和L3
都改变了。
相反,deepcopy
当不需要浅拷贝时,您可以这样做:
>>> from copy import deepcopy
>>> L3 = deepcopy(L1)
>>> L3
[1, [2, 3, 9], 4]
>>> L3 is L1
False