python del for循环中的一个元素

时间:2018-03-30 13:52:36

标签: python list enumerate

对于具有枚举的循环,当在循环内删除元素时,不会抛出索引超出范围错误吗?

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

2 个答案:

答案 0 :(得分:1)

这两个代码错误(请参阅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循环捕获StopIteration迭代器上next引发的enumerate异常这一事实:

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))。所以过了一会儿,索引超出了缩短列表的范围。

第一种情况不会崩溃,但结果很难理解,实现定义,不能依赖。不要这样做。

答案 1 :(得分:0)

在带范围的第二个代码中,解释器实际上扩展了你的范围循环,因此它会尝试打印(L [2])而你的列表只有两个值。