遍历列表删除项时,有些项未被删除
我正在尝试把一个列表的内容转移到另一个列表,但这没成功,我也不知道为什么。我的代码是这样的:
list1 = [1, 2, 3, 4, 5, 6]
list2 = []
for item in list1:
list2.append(item)
list1.remove(item)
但是当我运行它时,输出结果是这样的:
>>> list1
[2, 4, 6]
>>> list2
[1, 3, 5]
我有三个问题:为什么会这样,怎样才能让它正常工作,还有没有什么简单的解决办法,比如一个“移动”语句之类的?
10 个回答
调试的一个基本技能就是添加 print
语句。(在 Python 3 中用 print
函数)
>>> list1= [1, 2, 3, 4, 5, 6]
>>> for item in list1:
... print item
... list1.remove(item)
... print list1
...
1
[2, 3, 4, 5, 6]
3
[2, 4, 5, 6]
5
[2, 4, 6]
注意,Python 正在尝试逐个查看列表中的 位置,但你却不断从列表中删除项目,这样就让 位置 变得没有意义了。
Python 首先从列表中取出位置 0 的项目。
然后你把这个项目删除了,列表就变了。
接着,Python 再从列表中取出位置 1 的项目(看起来像是跳过了一个项目)。
你又把这个项目删除了,列表又变了。
然后,Python 继续从列表中取出位置 2 的项目(又看起来像是跳过了一个项目)。
你再次删除这个项目,列表又变了。
最后,Python 想要取出位置 3 的项目,但这个位置上已经没有项目了。所以循环就停止了。
你在遍历 list1 的时候同时删除里面的项目。
这样做很容易出问题。
试试这个方法:
>>> list1 = [1,2,3,4,5,6]
>>> list2 = []
>>> list2 = list1[:] # we copy every element from list1 using a slice
>>> del list1[:] # we delete every element from list1
原因是你在第一个列表上进行添加和删除操作,这样列表就变小了。所以在遍历整个列表之前,迭代器就停止了。
要实现你想要的效果,可以这样做:
list1 = [1, 2, 3, 4, 5, 6]
list2 = []
# You couldn't just make 'list1_copy = list1',
# because this would just copy (share) the reference.
# (i.e. when you change list1_copy, list1 will also change)
# this will make a (new) copy of list1
# so you can happily iterate over it ( without anything getting lost :)
list1_copy = list1[:]
for item in list1_copy:
list2.append(item)
list1.remove(item)
list1[start:end:step]
是一种叫做切片语法的写法:当你不填写start时,它默认是0;当你不填写end时,它就是列表能达到的最大值。所以 list1[:] 就表示列表中的所有内容。(感谢 Wallacoloo)
就像一些朋友说的,你也可以使用list
对象的extend
方法,把一个列表直接复制到另一个列表里,如果这就是你的目的。(但我选择了上面的方法,因为这更接近你的思路。)
既然你是Python新手,我给你推荐一个资源:Dive Into Python 3 - 这个是免费的,而且很简单。- 祝你玩得开心!