在Python中取N个列表的交集

7

什么是在Python中取N个列表的交集最简单的方法?

如果我有两个列表a和b,我知道可以这样做:

a = set(a)
b = set(b)
intersect = a.intersection(b)

我想做一些类似于a&b&c&d&...的事情,针对任意数量的列表(最好不要先转换为集合,但如果这是最简单/最有效的方法,我可以处理)。即,我想编写一个intersect(*args)函数,可以高效地处理任意多个集合。最简单的方法是什么?我的解决方案是reduce(set.intersection,[a,b,c]) - 这个好吗?谢谢。

关于 reduce(),它并不是最好的选择,因为在 Python 3 中它正在被逐渐淘汰。而且据我所知,与 for 循环相比,它也更慢。 - Xavier Ho
请将任意数量列表的交集在Python中实现 - Gary Kerr
@Xavier:from functools import reduce。它已从builtins中删除,但并未完全淘汰。此外,你所听到的有关其速度的说法是高度不准确的:它可能比for循环快得多或慢得多。 - tzot
3个回答

14

这适用于1个或多个列表。0个列表的情况并不那么容易,因为它必须返回一个包含所有可能值的集合。

def intersection(first, *others):
    return set(first).intersection(*others)

因此,使用内置函数的美妙之处就在于此。 - jathanism

3
这适用于一个或多个列表,并且不使用多个参数:
>>> def intersection(*listas):
...     return set(listas[0]).intersection(*listas[1:]) 
...     
>>> intersection([1,2,3,4],[4,5,6],[2,4,5],[1,4,8])
set([4])
>>> intersection([1,2,3,4])
set([1, 2, 3, 4])
>>> 

我不确定这个答案是否比其他答案更好,无论如何。


2
lists = [[5,4,3], [4,2], [6,2,3,4]]

try:
    # the following line makes one intersection too much, but I don't think
    # this hurts performance noticably.
    intersected = set(lists[0]).intersection(*lists)
except ValueError:
    # no lists[0]
    intersected = set()

print intersected         # set([4])

集合可以与任何可迭代对象取交集,无需先将其转换为集合。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接