遍历列表删除项时,有些项未被删除

7 投票
10 回答
1040 浏览
提问于 2025-04-15 21:00

我正在尝试把一个列表的内容转移到另一个列表,但这没成功,我也不知道为什么。我的代码是这样的:

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 个回答

4

调试的一个基本技能就是添加 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 的项目,但这个位置上已经没有项目了。所以循环就停止了。

8

你在遍历 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
8

原因是你在第一个列表上进行添加和删除操作,这样列表就变小了。所以在遍历整个列表之前,迭代器就停止了。

要实现你想要的效果,可以这样做:

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 - 这个是免费的,而且很简单。- 祝你玩得开心!

撰写回答