在使用Python解决实际问题的时候,我们经常会遇到在遍历可迭代数据的时候,删除元素的场景。 这种操作是非常容易出错的,因为在对同一个可迭代对象, 同时进行遍历和删除的操作,如果处理不恰当,会导致代码得到错误的结果, 在这篇文章中,我们集中讨论一下这个问题。
背景案例, 删除一个list中所有为0 的元素:
lst = [1, 1, 0, 2, 0, 0, 8, 3, 0, 2, 5, 0, 2, 6]
for item in lst:
if item == 0:
lst.remove(item)
print lst
输出:(很明显答案是错误的)
[1, 1, 2, 8, 3, 2, 5, 0, 2, 6]
添加元素
list1.append('c')
list1.extend(['a', 'b'])
list1.insert(1, 'x')
list3 = list1 + list2
删除元素
del list1[2]
del list1[-1]
del list1[2:3]
list1.pop() # 删除最后一个元素
list1.pop(0)
list1.remove(2)
list1.clear()
复杂度分析:
insert(i, item) O(n)
append() O(1)
pop(i) O(n)
in O(n)
del O(n)
from collections import defaultdict
deep_dist = defaultdict(list)
dict1['key'] = value
xx = {'key': 'value'}
dict1.update(xx)
del dict1['key']
dict1.pop('key')
dict1.clear()
dict1.has_key('key')
if 'key' in dict2.keys()
if 'key' in dict1
复杂度分析
基于哈希算法,增删查的复杂度都为O(1)
set1.add(1)
set1.remove(1)
set1.discard(1)
a & b # 交集
a | b # 并
a - b # 差
a ^ b # 不同时在两个集合中
复杂度分析:
原理是哈希表, 增删查的复杂度是O(1)
方案一:
采用for 循环倒序遍历的方式, 从列表末尾向前遍历, 这样删除元素时不会影响前面元素的索引。
my_list = [1, 2, 3, 4, 5]
to_delete = [3, 5]
for i in range(len(my_list) - 1, -1, -1):
if my_list[i] in to_delete:
del my_list[i]
print(my_list)
方案二:
遍历拷贝的list, 操作原始的list
for item in list1[:]:
if item == 0:
list1.remove(item)
print list1
方案三:
逆向思维,将希望保留的元素添加到一个新的列表中,就是想要的结果。
lis = [1,2,3,4]
new_lis = []
for i in lis:
if i == 4:
new_lis.append(i)
print(new_lis)
小结:
删除操作的时间复杂度应该是O(n), 个人还是比较喜欢方案一的实现方式, 这个方便实现更复杂的判断逻辑。
方案一:
dict无法在迭代中删除元素, 可以把keys改为一个list, 然后遍历list 来删除dict的元素。
keys = list(d.keys())
for key in keys:
if key == 'three':
del d[key]
方案二:
可以直接创建出一个新的字典, 使用推导式。
m_dict = {'a': 1, 'b': 2}
new_dict = {key: value for key, value in my_dict.items() if key != 'a'}
返回的新字典就是删除之后的字典。
小结: 个人倾向于使用keys 列表化的方式删除字典元素, 相比较而言, 这样更节省空间。
在原set 上进行删除操作是会抛出异常的。
方案一: 可以使用copy()方法, 在原来的set上进行删除, 在新的set上进行遍历。 如下所示:
my_set = {1,2,3,4,5}
for i in my_set.copy():
if i % 3 == 0:
my_set.remove(i)
print(my_set)
小结:
思路是对两个set操作, 一个遍历,一个删除,相互不影响。
本篇文章介绍了Python中list, dict 和set的遍历中删除元素的思路,处理类似的问题的时候,需要小心谨慎, 不然有可能很难定位出代码的bug。
https://blog.csdn.net/weixin_36372610/article/details/113582573