【问题标题】:How to remove a list of elements from a list?如何从列表中删除元素列表?
【发布时间】:2021-03-10 01:51:58
【问题描述】:

假设有列表AB

A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
B = [2, 4, 6]

我想修改A这样就变成了

A = [1, 3, 5, 7, 8, 9, 10]

我不想使用remove,因为A 可以有10k 个数字

【问题讨论】:

  • A 总是排序吗?
  • 排序或不排序都很好
  • 只是为了从A中删除B中的元素。
  • 你确定remove太慢了吗?
  • 顺便说一句,您被否决了,因为您自己没有表现出最小的努力来解决问题。 StackOverflow 是为了提供帮助,而不是为您提供完整的解决方案。

标签: python list


【解决方案1】:

如果您的用例允许;您可以使用set 操作,非常高效:

>>> A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> B = [2, 4, 6]
>>> A = list(set(A) - set(B))
>>> A
[1, 3, 5, 7, 8, 9, 10]

请注意,这不会使A 保持相同的顺序,并且会从中删除所有重复项。

slower faster 方式,but 以及在A 中保留重复项并保持其顺序的方式是使用列表理解。但是,您首先B 转换为set 以使in 操作尽可能快,这一点至关重要:

>>> A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> B = [2, 4, 6]
>>> set_b = set(B)
>>> A = [n for n in A if n not in set_b]
[1, 3, 5, 7, 8, 9, 10]

编辑:使用set 查找的列表理解实际上是更快的解决方案:

$ python3 -m timeit --number=1000 --setup='import random; A = random.sample(range(10 ** 6), 10 ** 5); B = random.sample(range(10 ** 6), 10 ** 4)' 'list(set(A) - set(B))'
1000 loops, best of 5: 18.7 msec per loop
$ python3 -m timeit --number=1000 --setup='import random; A = random.sample(range(10 ** 6), 10 ** 5); B = random.sample(range(10 ** 6), 10 ** 4)' 'set_b = set(B); [n for n in A if n not in set_b]'
1000 loops, best of 5: 11.8 msec per loop

【讨论】:

  • 但也有副作用,去除重复元素
  • @WasifHasan 但这似乎符合问题?不清楚。
  • @Thomas 考虑一个例子set([1,2,1])-set([2]),这里的预期输出应该是{1,1},但它会删除重复项,所以返回{1},是不是不正确?
  • 谢谢!我试过了,非常高效,很好用,谢谢
  • @WasifHasan 删除重复项可能很好。
【解决方案2】:

使用列表推导:

A = [x for x in A if x not in B]

【讨论】:

  • @WasifHasan 但这应该和remove的重复调用具有相同的复杂性?
  • @Thomas 时间复杂度很差,我无法提供更好的解决方案,除了 set() 已经介绍过
  • 如果 A 已排序,您可以使用二分搜索将您从 O(n·m) 带到 O(logn·m) - 但集合仍然会更快 :) 但话又说回来 - 集合不要像您在对另一个答案的评论中所展示的那样做与列表完全相同的事情。
猜你喜欢
  • 1970-01-01
  • 2010-10-13
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
  • 2014-12-19
  • 2013-11-25
相关资源
最近更新 更多