Python 在列表循环中的一些坑

循环内用 remove 删除列表自身元素

问题

for i in list 循环中,如果在循环内部使用 listremove 方法删除多个相邻的数据时,会出现漏删和输出信息错误; 当删除一个数据时,会出现输出信息错误。

例如:

# 创建一个 L list
# 删除相邻的多个数据
In [12]: L = [11, 22, 33, 44, 55, 66, 77]
In [13]: for i in L:
    ...:     if i == 22 or i == 33:
    ...:         L.remove(i)
    ...:     print(i)
    ...:  
# 想想这里 print 会打印出什么内容以及现在 L 的内容   
11
22
44
55
66
77
# 输出了本应该被删除的 22 
In [14]: L
# L 中本应该被删除的 33 没有被删除,
Out[14]: [11, 33, 44, 55, 66, 77]
# 如果你在一次性删除更多的数据或者全部整个列表用循环删除
# 会发现一个规律,remove 会隔一个数据删一个
In [20]: L = [11, 22, 33, 44, 55, 66, 77, 88]

In [21]: for i in L:
    ...:     L.remove(i)
    ...:     

In [22]: L
Out[22]: [22, 44, 66, 88]
# 创建一个 L list
# 删除单个数据
In [15]: L = [11, 22, 33, 44, 55, 66, 77]

In [16]: for i in L:
    ...:     print(i)
    ...:     if i == 33:
    ...:         L.remove(i)
    ...:         
11
22
33
55
66
77
# 输出了本应该被删除的 33 而本没有被删除的 44 却没有打印出来
In [17]: L
Out[17]: [11, 22, 44, 55, 66, 77]

原因

  • 存在一个指针

  • 在删除多个数据时,当删除第一项数据时后面的数据会往前移,使得指针指向删除的数据后面的一项

  • 然后在删除下一个时会跳过前一个被删除数据的下一项

解决

可以将需要删除的项取出来单独删除

通过 range 来删除列表中数据

问题

在通过 len(list)range 函数通过 for 循环来删除列表元素时,会出现报错

In [26]: L = [11, 22, 33, 44, 55, 66, 77, 88]

In [27]: for i in range(len(L)):
    ...:     if L[i] == 33:
    ...:         del L[i]
    ...:         
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-27-ced9d7033028> in <module>()
      1 for i in range(len(L)):
----> 2     if L[i] == 33:
      3         del L[i]
      4 

IndexError: list index out of range
# 上面提示超出索引范围

原因

原因当在循环中删除数据,然而 range 不会变,所以超出索引

解决

In [28]: L = [11, 22, 33, 44, 55, 66, 77, 88]

In [29]: for i in range(len(L)-1,-1,-1):
    ...:     if L[i] == 33:
    ...:         del L[i]
    ...:         

In [30]: L
Out[30]: [11, 22, 44, 55, 66, 77, 88]

range(start, end, step) ====> start->开始 end->结束 step->步长

range(len(L)-1, -1, -1) ====> 倒序

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值