从另一个列表中删除一个列表中的所有值?

我正在寻找一种方法来从另一个列表中删除列表中的所有值。

像这样的东西:

a = range(1,10) a.remove([2,3,7]) print aa = [1,4,5,6,8,9] 
 >>> a = range(1, 10) >>> [x for x in a if x not in [2, 3, 7]] [1, 4, 5, 6, 8, 9] 

如果你没有重复的值,你可以使用设置差异。

 x = set(range(10)) y = x - set([2, 3, 7]) # y = set([0, 1, 4, 5, 6, 8, 9]) 

然后根据需要转换回列表。

 a = range(1,10) itemsToRemove = set([2, 3, 7]) b = filter(lambda x: x not in itemsToRemove, a) 

要么

 b = [x for x in a if x not in itemsToRemove] 

不要在lambda内部或理解内部创build集合。 如果这样做,它会在每一次迭代中被重新创build,从而破坏了使用set的一点。

我正在寻找快速的方法来做这个主题,所以我用build议的方法做了一些实验。 我对结果感到惊讶,所以我想和大家分享一下。

实验使用pythonbenchmark工具和

 a = range(1,50000) # Source list b = range(1,15000) # Items to remove 

结果:

  def comprehension(a, b): return [x for x in a if x not in b] 

5次尝试,平均时间12.8秒

 def filter_function(a, b): return filter(lambda x: x not in b, a) 

5次尝试,平均时间12.6秒

 def modification(a,b): for x in b: try: a.remove(x) except ValueError: pass return a 

5次尝试,平均时间0.27秒

 def set_approach(a,b): return list(set(a)-set(b)) 

5次尝试,平均时间为0.0057

另外我做了另一个测量,input大小为最后两个function

 a = range(1,500000) b = range(1,100000) 

结果是:

对于修改(移除方法) – 平均时间是252秒对于设定的方法 – 平均时间是0.75

所以你可以看到使用set的方法比其他方法快得多。 是的,它不保留类似的项目,但如果你不需要它 – 这是给你的。 列表理解和使用过滤函数几乎没有区别。 使用“删除”快了50倍,但它修改了源列表。 最好的select是使用套件 – 比列表理解速度快1000倍!

其他人已经提出了在过滤之后build立新列表的方法

 newl = [x for x in l if x not in [2,3,7]] 

要么

 newl = filter(lambda x: x not in [2,3,7], l) 

但是从你的问题来看,你希望进行就地修改,因为你可以做到这一点,如果原始列表很长,并且要移除的项目较less

 l = range(1,10) for o in set([2,3,7,11]): try: l.remove(o) except ValueError: pass print l 

输出:[1,4,5,6,8,9]

我正在检查ValueErrorexception,所以即使项目不在原始列表中,它也能正常工作。

另外如果你不需要S.Mark的就地修改解决scheme更简单。

最简单的方法是

 >>> a = range(1, 10) >>> for x in [2, 3, 7]: ... a.remove(x) ... >>> a [1, 4, 5, 6, 8, 9] 

一个可能的问题是,每次调用remove()时,所有的项目都在列表中进行整理以填补空缺。 所以如果变得非常大,最终会变得非常慢。

这样build立一个全新的名单。 好处是我们避免了第一种方法的所有混乱

 >>> removeset = set([2, 3, 7]) >>> a = [x for x in a if x not in removeset] 

如果你想修改a地方,只需要一个小的改变

 >>> removeset = set([2, 3, 7]) >>> a[:] = [x for x in a if x not in removeset] 
 >>> a=range(1,10) >>> for i in [2,3,7]: a.remove(i) ... >>> a [1, 4, 5, 6, 8, 9] >>> a=range(1,10) >>> b=map(a.remove,[2,3,7]) >>> a [1, 4, 5, 6, 8, 9] 

要从列表中删除子列表,您可以处理要删除的子列表的索引,例如:

 a = [[1,2],[3,4],[5,6]] a.remove(a[1]) # removes the second sublist