zoukankan      html  css  js  c++  java
  • python循环删除列表元素常见错误与正确方法

    常见错误一:使用固定长度循环删除列表元素

    l = ['a','b','c']
    for i in range(len(l)):
        l.pop(i)

    报错:
    ValueError: list.remove(x): x not in list

    原因:
    在删除list中的元素后,list的实际长度变小了,但是循环次数没有减少,依然按照原来list的长度进行遍历,所以会造成索引溢出。是的,i的值是一开始就生成好了(0,1,2),后面不会因为列表大小变化了再变化。

    图示:

    执行第一次pop前,i是0


    执行第一次pop后,删除了索引0原来的a



    执行第二次pop前,i是1



    执行第二次pop后,删除了索引1原来的c



    执行第三次pop前,i是2。继续执行pop,索引2已超出了列表范围(此时列表只有索引0了)。


    解决方法:倒序循环遍历

    l = ['a','b','c']
    for i in range(len(l)-1, -1, -1):
        l.pop(i)

    常见错误二:正序循环遍历删除列表元素

    l = ['a','b','c']
    for i in l:
        l.remove(i)
    print l

    结果:
    ['b']

    原因:
    按顺序循环删除,怎么会有一个没删除呢?原因同上,i的值是一开始就生成好了(0,1,2),后面不会因为列表大小变化了再变化。但是列表因为值的删除,是在变化的。

    图示:
    执行第一次remove前,i是索引0的a



    执行第一次remove后,i是索引0的a被删除


    执行第二次remove前,i是索引1的c



    执行第二次remove后,i是索引1的c被删除。之后继续执行i是索引2,此时列表已经没有索引2了,循环退出。最后b就被剩下了。


    解决方法一:倒序循环遍历:

    l = ['a','b','c']
    for i in l[::-1]:
        l.remove(i)
    print l

    解决方法二:深拷贝一个ll,对l遍历,对ll操作

    l = ['a','b','c']
    ll = l[:]
    for i in l:
        ll.remove(i)

    此方法的缺点是对于过大的list,拷贝后可能很占内存。那么对于这种情况,可以用倒序遍历的方法来实现。

    ---------------------------------------------------------------------------------

    关注微信公众号(测试工程师小站)即可在手机上查阅,并可接收更多测试分享,发送【测试资料】更可获取百G测试教程~

  • 相关阅读:
    剑指offer——最小的K个数和数组中第K大的元素
    Leetcode刷题指南链接整理
    160. Intersection of Two Linked Lists
    100. Same Tree
    92. Reverse Linked List II
    94. Binary Tree Inorder Traversal
    79. Word Search
    78,90,Subsets,46,47,Permutations,39,40 DFS 大合集
    0x16 Tire之最大的异或对
    0x16 Tire
  • 原文地址:https://www.cnblogs.com/songzhenhua/p/12993189.html
Copyright © 2011-2022 走看看