• Python遍历列表时删除元素


    tk在科学养猪群里问bluerust、scz是否碰上过这个Python坑,示例1

    bas = [ 'ba1', 'ba2', 'ba3', 'ba4', 'ba5' ]
    for ba in bas :
        print( ba )
        if ( ba.find( 'ba' ) != -1 ) :
            bas.remove( ba )
            print( bas )
    
    print( bas )
    

    即遍历list的过程中动态删除元素。上述代码输出如下

    ba1
    ['ba2', 'ba3', 'ba4', 'ba5']
    ba3                             // ba2被跳过去了
    ['ba2', 'ba4', 'ba5']
    ba5                             // ba4被跳过去了
    ['ba2', 'ba4']
    ['ba2', 'ba4']                  // 列表未删干净
    
    

    对示例1做点改动,示例2

    bas = [ 'ba1', 'ba2', 'ba3', 'ba4', 'ba5' ]
    for i in range( len( bas ) ) :
        print( i )
        print( bas[i] )
        if ( bas[i].find( 'ba' ) != -1 ) :
            del bas[i]
            print( bas )
    
    print( bas )
    

    上述代码输出如下

    0
    ba1
    ['ba2', 'ba3', 'ba4', 'ba5']
    1
    ba3
    ['ba2', 'ba4', 'ba5']
    2
    ba5
    ['ba2', 'ba4']
    3
    Traceback (most recent call last):
      File "", line 3, in 
    IndexError: list index out of range
    ['ba2', 'ba4']
    

    循环变量i只递增到3,进而抛出IndexError。

    该坑的起因是,for循环中i的取值从最开始就固定了,实际上要求list在for循环中保持不变;遍历list的过程中动态删除元素,导致list发生变化,而i仍固执地按原计划递增遍历list,于是漏删元素、索引越界。

    对此,wzhvictor给了5种解决方案。

    方式1,利用filter函数

    bas = [ 'ba1', 'ba2', 'ba3', 'ba4', 'ba5', 'tk' ]
    bas = list( filter( lambda ba:ba.find( 'ba' ) == -1, bas ) )
    print( bas )
    

    方法2,重新构造list

    bas = [ 'ba1', 'ba2', 'ba3', 'ba4', 'ba5', 'tk' ]
    bas = [ba for ba in bas if ba.find( 'ba' ) == -1]
    print( bas )
    

    方法3,遍历list的拷贝,对原始list进行删除操作

    bas = [ 'ba1', 'ba2', 'ba3', 'ba4', 'ba5', 'tk' ]
    for ba in bas[:] :
        if ( ba.find( 'ba' ) != -1 ) :
            bas.remove( ba )
    
    print( bas )
    

    方法4

    bas = [ 'ba', 'ba', 'ba', 'ba', 'ba', 'tk' ]
    while 'ba' in bas :
        bas.remove( 'ba' )
    
    print( bas )
    

    方法5,倒序遍历

    bas = [ 'ba1', 'ba2', 'ba3', 'ba4', 'ba5', 'tk' ]
    for i in range( len( bas )-1, -1, -1 ) :
        if ( bas[i].find( 'ba' ) != -1 ) :
            del bas[i]
    
    print( bas )
    

    就tk的示例1而言,方法4其实不适用,方法4适合从list中删除所有特定值。

    这个坑我没踩过,用过方法2、3、4或者它们的变种。没像wzhvictor那样细究过for循环中i取值从最开始就固定,但我本能地对循环中动态处理的对象不放心,又懒得看Python文档,所以要么重新构造list,要么复制list再操作,完美避坑。今日看了wzhvictor的文章,方法1没用过,方法5没想过,方法5比较骚包,我第一次见。

    Python表面上的不确定性真多,也没啥大不了,我的经验是,能用简明直观确定性的写法,就不要骚包玩花活,性能优化是后话。再就是,单元测试,无需再多强调。

  • 相关阅读:
    what is bsp in rtems
    React报错之React Hook useEffect has a missing dependency
    【BUG修复日志】Anaconda + VSCode 编码错误
    HTML5七夕情人节表白网页制作【新年倒计时白色雪花飘落】HTML+CSS+JavaScript CSS特效
    Auto-WEKA(Waikato Environment for Knowledge Analysis)
    分布式协同AI基准测试项目Ianvs:工业场景提升5倍研发效率
    Redis管理客户端,兼容Windows、Mac、Linux
    Java多商户新零售超市外卖商品系统
    Jenkins-安装(2)
    【Spring Cloud】新闻头条微服务项目:引入ElasticSearch建立文章搜索索引
  • 原文地址:https://blog.csdn.net/m0_72557783/article/details/126712669