你真的会删除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

hmoban主题是根据ripro二开的主题,极致后台体验,无插件,集成会员系统
自学咖网 » 你真的会删除list元素么