Remove all the elements that occur in one list from another
假设我有两个列表,
我可以想到一个简单的循环方法来实现这一点,但这将是非常低效的。做这件事的方法是什么?
例如,如果我有
Python有一个称为列表理解的语言特性,非常适合让这类事情变得非常简单。以下语句完全满足您的需要,并将结果存储在
1 | l3 = [x for x in l1 if x not in l2] |
希望这有帮助!
一种方法是使用集合:
1 2 | >>> set([1,2,6,8]) - set([2,3,5,8]) set([1, 6]) |
扩展到油炸圈饼的答案和其他答案,通过使用生成器理解而不是列表理解,以及使用
这里有一个对你有用的函数:
1 2 3 | def filter_list(full_list, excludes): s = set(excludes) return (x for x in full_list if x not in s) |
结果将是一个iterable,它将懒惰地获取筛选列表。如果您需要一个真正的列表对象(例如,如果您需要对结果执行EDOCX1[5]),那么您可以轻松地构建这样的列表:
1 | filtered_list = list(filter_list(full_list, excludes)) |
使用python集类型。那将是最严重的Python。:)
而且,由于它是本地的,所以它也应该是最优化的方法。
见:
http://docs.python.org/library/stdtypes.html设置
http://docs.python.org/library/sets.htm(对于旧版python)
1 2 3 4 5 6 | # Using Python 2.7 set literal format. # Otherwise, use: l1 = set([1,2,6,8]) # l1 = {1,2,6,8} l2 = {2,3,5,8} l3 = l1 - l2 |
作为一种替代方法,您也可以将
1 2 3 4 5 6 7 | >>> l1 = [1,2,6,8] >>> l2 = set([2,3,5,8]) # v `filter` returns the a iterator object. Here I'm type-casting # v it to `list` in order to display the resultant value >>> list(filter(lambda x: x not in l2, l1)) [1, 6] |
性能比较
这里我比较一下这里提到的所有答案的性能。正如预期的那样,Arkku基于
Arkku的设置差异-第一个(每个循环0.124 usec)
1
2mquadri$ python -m timeit -s"l1 = set([1,2,6,8]); l2 = set([2,3,5,8]);""l1 - l2"
10000000 loops, best of 3: 0.124 usec per loopDaniel Pryden对
set 查找的列表理解-秒(每个循环0.302 usec)1
2mquadri$ python -m timeit -s"l1 = [1,2,6,8]; l2 = set([2,3,5,8]);""[x for x in l1 if x not in l2]"
1000000 loops, best of 3: 0.302 usec per loop甜甜圈的清单理解在普通清单-第三个(0.552个使用循环)
1
2mquadri$ python -m timeit -s"l1 = [1,2,6,8]; l2 = [2,3,5,8];""[x for x in l1 if x not in l2]"
1000000 loops, best of 3: 0.552 usec per loopMoinuddin Quadri使用
filter 四分之一(每个循环0.972 usec)1
2mquadri$ python -m timeit -s"l1 = [1,2,6,8]; l2 = set([2,3,5,8]);""filter(lambda x: x not in l2, l1)"
1000000 loops, best of 3: 0.972 usec per loopAkshay Hazari使用
reduce +filter -第五个(每个回路3.97 usec)1
2mquadri$ python -m timeit"l1 = [1,2,6,8]; l2 = [2,3,5,8];""reduce(lambda x,y : filter(lambda z: z!=y,x) ,l1,l2)"
100000 loops, best of 3: 3.97 usec per loop
ps:
替代解决方案:
1 | reduce(lambda x,y : filter(lambda z: z!=y,x) ,[2,3,5,8],[1,2,6,8]) |