• Python中遍历列表remove漏删解决方案


    需求及背景

    我有一个需求:保留list_1中含有list_2元素的元素,其他的删除

    list_1 = ['魁哥','夭夭', '阿离', '渣姐', '秃头企鹅', '王哥', '小白', '卷魔']
    list_2 = ['旺仔', '秃头企鹅', '王哥']
    
    • 1
    • 2

    最后需要输出

    ['秃头企鹅', '王哥']
    
    • 1

    直接一顿操作,写出了如下代码

    for i in list_1:
        if i not in list_2:
            list_1.remove(i)
    print(list_1)
    
    • 1
    • 2
    • 3
    • 4

    结果输出的结果是

    ['夭夭', '渣姐', '秃头企鹅', '王哥', '卷魔']
    
    • 1

    为什么会这样?通过debug发现,每删除一个元素,list_1里面的元素下标就会发生变化,而for循环里面是持续性的读取下一个值的,每次删除一个的时候,便会跳过一个。

    既然如此我就是用下标删呗

    for i in range(len(list_1)):
        if list_1[i] not in list_2:
            list_1.remove(list_1[i])
            continue
    print(list_1)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这时候又发现,直接报错

    IndexError: list index out of range
    
    • 1

    当删除一个元素之后,新列表的长度减少,i 还是根据原来列表的索引取值,当 i 超过当前的列表长度时,新列表没有该下标对应元素,索引越界。

    解决办法

    方案一(快捷)

    list_1 = ['夭夭', '阿离', '渣姐', '秃头企鹅', '魁哥', '小白', '卷魔']
    list_2 = ['旺仔', '秃头企鹅', '王哥']
    j = 0
    for i in range(len(list_1)):
        if list_1[j] not in list_2:
            list_1.remove(list_1[j])
            continue
        j+=1
    print(list_1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    方案一方法的思路:

    每次只要删除了,都从上一次的下标继续,如果这次没删除,则下标加一删下一个。看不太懂的可以丢自己编辑器里面加一些print进行分步分析。

    输出

    ['秃头企鹅', '王哥']
    
    • 1

    方案二(简单)

    倒序
    如果让索引倒序遍历列表就不会出现越界的问题了。

    for i in range(len(list_1)-1,-1,-1):
        if list_1[i] not in list_2:
            list_1.remove(list_1[i])
    print(list_1)
    
    • 1
    • 2
    • 3
    • 4

    方案二方法思路:

    将索引倒序,这样不管你怎么删,我下标都是倒着来,肯定不会下标越界。(此方法对应解决最开始的下标越界的思路。)

    注意细节:(自己多尝试,多写)

    ①len减一是因为左闭右开;

    ②第三个参数表示的是对数值所进行的操作,每次加上-1;

    ③第二个值表示最终加到-1,但不包含-1。(最终加到几,但是不包含本身)

    输出

    ['秃头企鹅', '王哥']
    
    • 1

    方案三(粗暴)

    while True:
        for i in list_1:
            if i not in list_2:
                list_1.remove(i)
                break
        else:
            break
    print(list_1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    方案三思路:

    无限循环,知道你搞完,这个不多解释,就是莽夫。

    输出

    ['秃头企鹅', '王哥']
    
    • 1

    方案四(灵活)

    d = dict(zip(range(len(list_1)),list_1))
    for k,v in d.items():
        if v not in list_2:
            d[k]=[]
    final_1 =  [v for k,v in d.items() if v]
    print(final_1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    方案四思路:

    讲列表转换成字典,再通过字典的value和list_2进行对比,如果不是list_2中的元素则赋值为空列表,最后拿到不是空列表的value,就是我们需要的列表了。

    听起来会有点绕,自己尝试一下,一下就练了字典、列表、遍历、推导式、列表合并字典这些知识点哦。

    输出

    ['秃头企鹅', '王哥']
    
    • 1

    上面用例列表推导式,zip,dict等方法,这些python基础我之前文章有写,大家可以多翻翻。(如果没有,那肯定是我不小心删了。)

    最后,祝大家周末愉快!

    gzh:梦无矶的测试开发之路

  • 相关阅读:
    字体族与图标字体
    【Top101】002链表内指定区间反转
    汉语言语的声学特点是什么
    C++学习之旅 第一章 C++预备知识
    从maven开始你的spring开发
    03 最小CMake项目
    出海不出局 | 小游戏引爆高线市场,新竞争态势下的应用出海攻略
    网络基础知识点
    【Java 进阶篇】Cookie 使用详解
    14数据结构与算法刷题之【深搜&宽搜递归&分治&剪枝回溯】篇
  • 原文地址:https://blog.csdn.net/qq_46158060/article/details/126895090