删除从另一个列表中出现的所有元素
假设我有两个列表, l1
和l2
。 我想执行l1 - l2
,它返回l1
中的所有元素,而不是l2
。
我可以想到一个天真的循环方法来做到这一点,但这将是非常低效的。 什么是pythonic和有效的方式做到这一点?
举个例子,如果我有l1 = [1,2,6,8] and l2 = [2,3,5,8]
, l1 - l2
应该返回[1,6]
Python有一个名为List Comprehensions的语言特性,非常适合使这种事情变得非常简单。 下面的语句完全是你想要的,并将结果存储在l3
:
l3 = [x for x in l1 if x not in l2]
l3
将包含[1, 6]
。
希望这可以帮助!
一种方法是使用集合:
>>> set([1,2,6,8]) - set([2,3,5,8]) set([1, 6])
通过使用生成器理解而不是列表理解,并且通过使用set
数据结构(因为in
运算符是O(n)而不是O(n)),所以可以得到更好的结果, 1)一套)。
所以这里有一个适用于你的函数:
def filter_list(full_list, excludes): s = set(excludes) return (x for x in full_list if x not in s)
结果将是一个迭代,将懒惰地获取过滤列表。 如果你需要一个真正的列表对象(例如,如果你需要对结果做一个len()
),那么你可以很容易地建立一个列表,如下所示:
filtered_list = list(filter_list(full_list, excludes))
使用Python集合类型。 这将是最Pythonic。 🙂
而且,因为它是本地的,所以它也应该是最优化的方法。
看到:
http://docs.python.org/library/stdtypes.html#set
http://docs.python.org/library/sets.htm (对于较老的python)
# 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
备用解决方案:
reduce(lambda x,y : filter(lambda z: z!=y,x) ,[2,3,5,8],[1,2,6,8])