我希望下面的循环迭代六次,而不是用python3迭代三遍。我不了解这种行为。 我知道列表在删除元素时会发生变化,但是我不知道那会如何影响for循环条件。 为什么循环迭代少于六次?
a = [1, 2, 3, 4, 5, 6]
for elem in a:
del a[0]
print(a)
答案 0 :(得分:4)
您将通过del a[0]
删除循环的每个迭代中的第一个元素,因此,迭代器将分3步清空,因为迭代器将在下一次迭代中删除的元素之后移至该元素。
您可以检查迭代器当前所在的元素,以及下面代码中的列表状态
a = [1, 2, 3, 4, 5, 6]
for elem in a:
print(elem)
del a[0]
print(a)
输出为
1
[2, 3, 4, 5, 6]
3
[3, 4, 5, 6]
5
[4, 5, 6]
您可以将其视为指向列表中第一个元素的指针,当您在每次迭代中删除第一个元素时,该指针跳2个步骤,而6个元素只能跳3次。
通常,修改要迭代的相同列表是一个坏主意。
但是,如果确实要删除,如果您确实要删除项目,则可以遍历列表a[:]
的副本
a = [1, 2, 3, 4, 5, 6]
for elem in a[:]:
del a[0]
print(a)
输出为
[2, 3, 4, 5, 6]
[3, 4, 5, 6]
[4, 5, 6]
[5, 6]
[6]
[]
答案 1 :(得分:2)
CPython中的list
迭代器通过遍历列表的位置来工作。您可以这样认为:
def list_iter(items: list):
index = 0
while True:
yield items[index]
index += 1
换句话说,迭代提供的项为0,然后为1,然后为2,依此类推。没有预取项目-需要时从列表中查找项目。
在每个步骤中删除第一项时,该列表在每个步骤中都会缩短1。由于您从6个项目的列表开始,因此在第三次迭代中它减少到3个项目-意味着第四次迭代无法查找项目。这样,您的迭代将在三个步骤之后结束。
在每个循环中同时打印当前元素时,您会看到此信息。要可视化效果,请使用enumerate
获取迭代索引。请注意,它前进了一个索引,但值也偏移了两个偏移量:
>>> a = [1, 2, 3, 4, 5, 6]
... for idx, elem in enumerate(a):
... print(elem, 'from', a)
... print(' ', ' '*idx, '^')
... del a[0]
...
1 from [1, 2, 3, 4, 5, 6]
^
3 from [2, 3, 4, 5, 6]
^
5 from [3, 4, 5, 6]
^
在容器上进行迭代时,通常没有很好的定义。您应该改为遍历副本:
a = [1, 2, 3, 4, 5, 6]
for elem in a.copy():
del a[0]
print(a)
答案 2 :(得分:1)
反复遍历和从列表中删除元素非常棘手。一种管理方式是反向遍历列表:
a = [1, 2, 3, 4, 5, 6]
for elem in reversed(a):
print(a)
del a[0]
print(a)
它将打印:
[1, 2, 3, 4, 5, 6]
[2, 3, 4, 5, 6]
[3, 4, 5, 6]
[4, 5, 6]
[5, 6]
[6]
[]