你真的会删除list元素么
先来看一段代码:
(推荐学习:Python入门教程)
# Delete elements from a list def remove_list(li,drop_list): for i in li: inx = li.index(i) if i in drop_list: del li[inx] print(li) li1 = [1, 2, 2, 2, 3] drop_list = [2] remove_list(li, drop_list) > [1, 2, 3]
这段代码并没有把所有“2”删除掉,为了发现它二在哪里,继续举两个例子。
# Delete a2 & a3 li2 = ["a1", "a2", "a3", "a4", "a5", "a6", "a7"] drop_list = ["a2", "a3"] remove_list(li, drop_list) > ['a1', 'a3', 'a4', 'a5', 'a6', 'a7'] #Delete all the list li3 = ["a1", "a2", "a3", "a4", "a5", "a6", "a7"] drop_list = ["a1", "a2", "a3", "a4", "a5", "a6", "a7"] remove_list(li, drop_list) > ['a2', 'a4', 'a6']
这下问题清楚了,但凡相连元素的删除,后面的那个元素总是能风骚走位。所以很明显,是因为删除的过程中,删除了前一个元素后,整个列表会整体前移,索引值发生了改变,导致紧随其后的元素在接下来的遍历中无法被检索。
解决方案:
上面其实出现了两个问题,分别是删除相同的所有元素及删除两个相邻的元素,解决的思路也稍有不同。
删除同一元素
1、可以使用while和remove的组合
while 2 in li1: li1.remove(2) print(li1) > [1, 3] # 2、倒序遍历法 for i in li1[::-1]: if i == 2: li1.remove(i) print(li1) > [1, 3]
删除相邻元素
1、列表解析
new_li2 = [i for i in li2 if i != "a2" or i != "a3"] print(new_li2) > ['a1', 'a4', 'a5', 'a6', 'a7'] # 2、使用filter new_li2 = filter(lambda i: i != "a2" or i != "a3", li2) print(list(new_li2)) > ['a1', 'a4', 'a5', 'a6', 'a7'] # 3、一次遍历创建新表 new_li2 = [] for i in li2: if i != "a2" or i != "a3": new_li2.append(temp) print(list(new_li2)) > ['a1', 'a4', 'a5', 'a6', 'a7']
其实可以看到,在这个例子中,i!="a2" or i!="a3"i !=" a 2 " ext { or } i !=" a 3 "i!="a2" or i!="a3"是最关键的解析式,如果我们对解析式进行修改,那么就可以删除多个元素了。
new_li3 = [] for i in li3: if i not in ["a1", "a2", "a3", "a4", "a5", "a6", "a7"]: new_li3.append(temp) print(list(new_li3)) > []
小结
使用while或倒序循环的方法,可以删除同一元素,而使用其他几种方法,可以删除任意元素,包括相邻的元素。如果这些元素还具有其它特征,那可能会有其它更简便的方法,比如使用itertools库之类的。
pop、del与remove
最后顺便说说列表中的这三个针对单个元素的删除方法。上面重复用到的是remove,一开始写的代码也和remove的思路几乎一致。但是这三个方法还是有一点区别的。
li4 = [1, 2, "a1", "a2", "a1"] # 使用del语句可以删除任何位置处的列表元素,条件是知道索引 print(del li4[2]) > [1, 2, "a2", "a1"] # pop是列表自带的方法,和del几乎一样,缺省值意味删除最后一个元素,也需要知道索引 print(li4.pop()) print(li4.pop(2)) > [1, 2, "a1", "a2"] > [1, 2, "a2", "a1"] # remove针对不知道元素在列表中的位置,但知道元素的值的情形,但对于多个相同的元素,只能删除第一个 # 使用上面说的while就可以删除多个相同元素 print(li4.remove("a1")) print((li4.remove("a1")).remove("a1")) > [1, 2, "a2", "a1"] > [1, 2, "a2"]
总结
删除列表中指定元素时,最好不要用 for 循环(或本质就是for循环的一切内容),删除不当实际上是一个非常危险的bug,实际开发中,如果应该被删除但是却被漏掉的垃圾会不断累积直到造成内存溢出。上面提供的方法应该可以解决大部分的情形了。
来源:PY学习网:原文地址:https://www.py.cn/article.html