我原以为下面的循环会迭代六次,而实际上使用python3只迭代了三次。我不理解这种行为。
我知道当我删除元素时,列表会发生变化,但我不知道它如何影响for循环的条件。
为什么这个循环迭代的次数少于六次?
a = [1, 2, 3, 4, 5, 6]
for elem in a:
del a[0]
print(a)
a = [1, 2, 3, 4, 5, 6]
for elem in a:
del a[0]
print(a)
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]
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]
[]
del [0]
,缺少了 a
。它不允许我编辑它。 - Zois Tasoulas在CPython中,list
迭代器通过迭代列表的位置来工作。你可以把它看作是这样工作的:
最初的回答:
CPython中的list
迭代器通过遍历列表的位置来工作。你可以将其想象为以下方式:
def list_iter(items: list):
index = 0
while True:
yield items[index]
index += 1
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)
index += 1
吗? - Supratim Haldar同时迭代和删除列表中的元素比较棘手。一个处理方法是以相反的顺序遍历列表:
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]
[]
reverse(a)
起作用。 - Supratim Haldar