当循环内删除元素时,带有枚举的 For 循环不会引发索引超出范围错误?
L = [1, 4, 8, 5]
try:
for i,item in enumerate(L):
print("Value of {} is {}".format(i, item))
del L[i]
except IndexError as e:
print("Index error: {err}.".format(err=e))
输出:
Value of 0 is 1
Value of 1 is 8
虽然此代码会导致错误
L = [1, 4, 8, 5]
try:
for i in range(len(L)):
print("Item:", L[i])
del(L[i])
except IndexError as e:
print("Error:", e)
输出:
Item: 1
Item: 8
Error: list index out of range
最佳答案
这两个代码都是错误的(参见 How to remove items from a list while iterating? ),但两种情况的症状不同。
在第一种情况下,您迭代L
。缩短 L
使迭代结束得更快(请注意,有些项目被跳过,因为缩短列表会混淆内部迭代器,从而引发 StopIteration
,从而停止 for
循环)
您可以使用 while
循环创建第一种情况的一些等效代码:
L = [1, 4, 8, 5]
try:
i = 0
while i < len(L):
print("Item:", L[i])
del(L[i])
i += 1
except IndexError as e:
print("Error:", e)
或模拟以下事实:for
循环捕获 enumerate
迭代器上的 next
引发的 StopIteration
异常:
e = enumerate(L)
while True:
try:
i,item = next(e)
print("Value of {} is {}".format(i, item))
del L[i]
except StopIteration:
break
你会得到相同的结果,因为len(L)
在每次迭代时都会被评估,所以索引不能越界(但结果不是很好)也有用)
在第二种情况下,您已使用初始列表大小计算了 range(len(L))
。因此一段时间后,索引超出了缩短列表的范围。
第一种情况不会崩溃,但结果很难理解,实现定义的,不能依赖。不要这样做。
关于python 在for循环中删除一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49575756/