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操作(列表交集)?


当前回答

在这种情况下,你有一个列表的列表地图很方便:

>>> 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()

其他回答

使用过滤器和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封装它返回输出列表。

对我来说,使用列表推导式是一个非常明显的方法。不确定性能如何,但至少能保持列表。

[x for x in a if x in b]

或者"所有在A中的x值,如果x值在B中"

如果你将两个列表中较大的一个转换为一个集合,你可以使用intersection()获得该集合与任何可迭代对象的交集:

a = [1,2,3,4,5]
b = [1,3,5,6]
set(a).intersection(b)

这是一个示例,当您需要在结果中的每个元素出现的次数应该与它在两个数组中显示的次数相同。

def intersection(nums1, nums2):
    #example:
    #nums1 = [1,2,2,1]
    #nums2 = [2,2]
    #output = [2,2]
    #find first 2 and remove from target, continue iterating

    target, iterate = [nums1, nums2] if len(nums2) >= len(nums1) else [nums2, nums1] #iterate will look into target

    if len(target) == 0:
            return []

    i = 0
    store = []
    while i < len(iterate):

         element = iterate[i]

         if element in target:
               store.append(element)
               target.remove(element)

         i += 1


    return store

你也可以使用计数器!它不会保留顺序,但会考虑副本:

>>> from collections import Counter
>>> a = [1,2,3,4,5]
>>> b = [1,3,5,6]
>>> d1, d2 = Counter(a), Counter(b)
>>> c = [n for n in d1.keys() & d2.keys() for _ in range(min(d1[n], d2[n]))]
>>> print(c)
[1,3,5]