为什么在for-loop中del list [0]只删除列表的一半?

时间:2017-08-14 21:55:52

标签: python list loops

我有以下代码,它只使用for循环删除了一半的列表。为什么会这样?另外,如何删除遍历它的列表的第一个元素?

list = [1,2,3,4,5,6,7,8,9,10]
for x in list:
    print list[0]
    del list[0]
print list 

输出:

1 
2
3
4
5
[6, 7, 8, 9, 10]

2 个答案:

答案 0 :(得分:3)

问题是你从列表中删除但列表迭代器并不知道并且很乐意处理剩下的"列表。

因此,在第一次迭代中,迭代器位于索引0并且您删除了索引0,在下一次迭代中,迭代器返回索引1(在删除第一个项之前它将是索引2处的项)并且它将删除索引0在下一次迭代中,您将获得索引2处的项目(最初位于索引4处,但因为您删除了两个项目现在位于索引2处),依此类推。最后,只要索引大于列表中剩余的项目,它就会停止,因为您为原始列表的中间(一半)处理的每个项目删除了一个项目。

长话短说:不要修改你重复的列表。

如果您真的想做类似的事情,那么您可以使用while循环:

lst = [1,2,3,4,5,6,7,8,9,10]
while lst:   # as long as the lst contains items
    print lst[0]
    del lst[0]
print lst 

或迭代副本:

lst = [1,2,3,4,5,6,7,8,9,10]
for x in lst[:]:   # [:] makes a shallow copy of a list
    print lst[0]
    del lst[0]
print lst 

注意:list是Python的内置函数的名称,因此如果您有一个具有相同名称的变量,则会影响此函数。这就是为什么我将变量名称更改为lst

答案 1 :(得分:3)

这里发生的是你正在迭代它时更改列表,让我们看一下循环的迭代

1st iteration:

pointer
  |
  V
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

现在你从列表中删除了数字1,但是指针仍然会移动到下一个项目,这就是问题

2nd iteration:

  pointer
     |
     V
 [2, 3, 4, 5, 6, 7, 8, 9, 10]

下一次迭代,数字2将被删除,指针将前进。

3rd iteration:

     pointer
        |
        V
 [3, 4, 5, 6, 7, 8, 9, 10]



4th iteration:

        pointer
           |
           V
 [4, 5, 6, 7, 8, 9, 10]



5th iteration (last one):

           pointer
              |
              V
 [5, 6, 7, 8, 9, 10]

现在打印列表并获得[6,7,8,9,10]。通过将行print list[0]更改为print list[0], x,您可以看到我所说的实际上是真正发生的事情,这样您就可以看到指针。

这将是输出:

1 1
2 3
3 5
4 7
5 9
[6, 7, 8, 9, 10]

可以采取哪些措施来解决这个问题?以下任何一种:

这将使x成为一个数字(列表中项目的索引),这意味着循环将进行len(list)次迭代(即10次迭代)

list = [1,2,3,4,5,6,7,8,9,10]

for x in range(len(list)):
    print list[0]
    del list[0]
print list 

这将使循环遍历原始列表的副本,因此它将循环10次,这足以删除列表中的所有项目。

list = [1,2,3,4,5,6,7,8,9,10]
copy = [1,2,3,4,5,6,7,8,9,10]

for x in copy:
    print list[0]
    del list[0]
print list