假设我有一个列表l
,并且我从l
生成新的列表temp
。当我尝试从temp
中删除元素时,它也会从l
中删除元素。这太奇怪了。如何仅从temp
中删除元素?
l = [1,2,3]
temp = l
temp.remove(3)
print(l, temp)
Output: ([1, 2], [1, 2])
实际上l
和temp
都是引用内存中相同对象list
的名称。当你用它们中的任何一个做某事时,你就是在对这两个名字所指向的底层对象列表进行操作。您总是可以使用复制方法创建一个新对象:
temp = l.copy()
这样,您将有两个指向不同对象的名称。
使用temp=l
创建列表时,python不会创建新对象。它指的是和temp
相同的对象,所以您所做的任何更改都将反映在原始列表中。使用copy
方法避免这种
l = [1,2,3]
temp = l.copy()
temp.remove(3)
print(l, temp)
输出:
[1, 2, 3] [1, 2]
如果这样做:
l = [1,2,3]
temp = l
您还没有创建一个新的列表,但您只是创建了对同一列表的新引用。通过任一变量更改列表会同时更改两个变量的列表。
要复制列表,您可以执行以下操作:
temp = list(l)
另一种方法是做temp = l[:]
,这是等价的。在Python 3中,您也可以执行temp = l.copy()
,但这在Python 2中不起作用。
然后,您可以在不影响另一个列表的情况下更改其中一个列表。
temp = l
只是将temp
分配给l
的引用。因此,无论你对一个列表做什么,另一个都会受到影响。
我们可以使用id()
功能进行检查:
print(id(l))
# 1739514774400
print(id(temp))
# 1739514774400
它为内存中的每个对象返回相同的唯一地址。
我们可以在文档中看到这一点:
返回对象的"标识"。这是一个整数,保证在该对象的生存期内是唯一的和常量。寿命不重叠的两个对象可能具有相同的id((值。
CPython实现细节:这是内存中对象的地址。
在这种情况下,l
和temp
是相同的,因此它们具有相同的身份。
我们可以通过分配副本来解决这个问题:
l = [1,2,3]
temp = l[:]
它现在给出了不同的身份,并且只从temp
:中删除了2
print(id(l))
# 1822815159168
print(id(temp))
# 1822815159104
temp.remove(3)
print(l, temp)
# [1, 2, 3] [1, 2]