2013-06-22 82 views
1

我有一个名为MyList的列表。 我要将列表复制到一个新的,然后将项目添加到新的,所以我做的:使用循环中的新项目与另一个列表进行标识

MySecondList=MyList 

for item in MyList: 
    if item==2: 
     MySecondList.append(item) 

我遇到的问题是,该项目也将被添加到MYLIST,并作为事实上,循环不断通过MyList新项目!

这是正常的吗?为什么会发生?不应该迭代使用它的原始列表MyList,而不是与我添加到其他列表中的项目一起增加?

回答

1

是的,名单在Python可变的,这个操作是正常的。

MySecondList = MyList 

简单地创建一个新的参考同一个列表对象,并list.append修改同一个对象就地(其他操作,如+=list.extendlist.pop等也修改就地列表)

可以使用浅拷贝这里:

MySecondList = MyList[:] 

演示:

>>> from sys import getrefcount 
>>> lis = [1,2,3] 
>>> foo = lis  #creates a new reference to the same object [1,2,3] 
>>> lis is foo 
True 
>>> getrefcount(lis) #number of references to the same object 
3     #foo , lis and shell itself 

#you can modify the list [1,2,3] from any of it's references 
>>> foo.append(4) 
>>> lis.append(5) 
>>> foo,lis 
([1, 2, 3, 4, 5], [1, 2, 3, 4, 5]) 

>>> lis = [1,2,3] 
>>> foo = lis[:] #assigns a shallow copy of lis to foo 
>>> foo is lis 
False 
>>> getrefcount(lis) #still 2(lis + shell_, as foo points to a different object 
2 

#different results here 
>>> foo.append(4) 
>>> lis.append(5) 
>>> foo, lis 
([1, 2, 3, 4], [1, 2, 3, 5]) 

对于列出的清单(或可变对象的列表)浅拷贝是不够的内部列表(或对象)是同一个对象只是新引用:

>>> lis = [[1,2,3],[4,5,6]] 
>>> foo = lis[:] 
>>> foo is lis    #lis and foo are different 
False 

>>> [id(x) for x in lis] #but inner lists are still same 
[3056076428L, 3056076716L] 
>>> [id(x) for x in foo] #same IDs of inner lists, i.e foo[0] is lis[0] == True 
[3056076428L, 3056076716L] 
>>> foo[0][0] = 100   # modifying one will affect the other as well 
>>> lis[0],foo[0] 
([100, 2, 3], [100, 2, 3]) 

对于这样的情况下,使用copy.deepcopy

>>> from copy import deepcopy 
>>> lis = [[1,2,3],[4,5,6]] 
>>> foo = deepcopy(lis) 
+0

非常感谢你 –

0

因为他们都引用相同的列表(和他们的id是相同的)。注意:

>>> a = [1,2,3] 
>>> b = a 
>>> b 
[1, 2, 3] 
>>> a is b 
True 
>>> b += [1] 
>>> b 
[1, 2, 3, 1] 
>>> a 
[1, 2, 3, 1] 
>>> a is b 
True 

而是执行此操作:

MySecondList = MyList[:] 

这样做是什么使得它不会改变原来的名单列表的副本。您也可以使用list(MyList)

+0

谢谢您的回答,也翔实:) –

相关问题