a = [1,2,3,4,5]
b = [1,3,5,6]
c = a and b
print c
实际输出:[1,3,5,6] 预期输出:[1,3,5]
如何在两个列表上实现布尔AND操作(列表交集)?
a = [1,2,3,4,5]
b = [1,3,5,6]
c = a and b
print c
实际输出:[1,3,5,6] 预期输出:[1,3,5]
如何在两个列表上实现布尔AND操作(列表交集)?
当前回答
使用过滤器和lambda运算符可以实现函数式的方法。
list1 = [1,2,3,4,5,6]
list2 = [2,4,6,9,10]
>>> list(filter(lambda x:x in list1, list2))
[2, 4, 6]
编辑:它过滤掉了同时存在于list1和list中的x,集差异也可以使用:
>>> list(filter(lambda x:x not in list1, list2))
[9,10]
python3 filter返回一个过滤器对象,用list封装它返回输出列表。
其他回答
这样可以得到两个列表的交集,也可以得到公共重复项。
>>> from collections import Counter
>>> a = Counter([1,2,3,4,5])
>>> b = Counter([1,3,5,6])
>>> a &= b
>>> list(a.elements())
[1, 3, 5]
在这种情况下,你有一个列表的列表地图很方便:
>>> lists = [[1, 2, 3], [2, 3, 4], [2, 3, 5]]
>>> set(lists.pop()).intersection(*map(set, lists))
{2, 3}
适用于类似的迭代对象:
>>> lists = ['ash', 'nazg']
>>> set(lists.pop()).intersection(*map(set, lists))
{'a'}
如果列表是空的,Pop会爆炸,所以你可能想要在一个函数中进行包装:
def intersect_lists(lists):
try:
return set(lists.pop()).intersection(*map(set, lists))
except IndexError: # pop from empty list
return set()
从较大的集合中创建一个集合:
_auxset = set(a)
然后,
c = [x for x in b if x in _auxset]
会做你想做的(保留b的顺序,而不是a的顺序——不一定能同时保留两者),而且动作要快。(使用a中的if x作为列表理解中的条件也可以工作,并且避免了构建_auxset的需要,但不幸的是,对于相当长的列表,它会慢得多)。
如果你想对结果进行排序,而不是保持列表的顺序,一个更整洁的方法可能是:
c = sorted(set(a).intersection(b))
如果布尔与是指同时出现在两个列表中的项,例如交集,那么你应该看看Python的set和frozenset类型。
如果顺序不重要,你不需要担心重复,那么你可以使用set intersection:
>>> a = [1,2,3,4,5]
>>> b = [1,3,5,6]
>>> list(set(a) & set(b))
[1, 3, 5]