我正在使用Python进行编程,可以获取两个列表的交集:
result = set(a).intersection(b)
现在假设 d
是一个列表,其中包含 a
和 b
这两个元素以及第三个元素 c
,那么是否有内置函数可以找到 d
中所有三个列表的交集?举例来说,
d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]
那么结果应该是
[3,4]
我正在使用Python进行编程,可以获取两个列表的交集:
result = set(a).intersection(b)
现在假设 d
是一个列表,其中包含 a
和 b
这两个元素以及第三个元素 c
,那么是否有内置函数可以找到 d
中所有三个列表的交集?举例来说,
d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]
那么结果应该是
[3,4]
set.intersection(*map(set,d))
对于版本为2.4,您可以定义一个intersection函数。
def intersect(*d):
sets = iter(map(set, d))
result = sets.next()
for s in sets:
result = result.intersection(s)
return result
对于较新版本的Python:
intersection方法可以接受任意数量的参数。
result = set(d[0]).intersection(*d[1:])
另一种方法是将第一个集合与其自身相交,以避免切片列表并进行复制:
result = set(d[0]).intersection(*d)
我不确定哪种方法更有效率,但感觉这将取决于 d [0]
的大小以及列表的大小,除非Python内置有针对此的检查。
if s1 is s2:
return s1
在交集方法中。>>> d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]
>>> set(d[0]).intersection(*d)
set([3, 4])
>>> set(d[0]).intersection(*d[1:])
set([3, 4])
>>>
intersection
方法。 - aaronasterlingTypeError: intersection() takes exactly one argument (3 given)
。 - Legendresult = set(d[0]).intersection(*d[:1])
应该是:
result = set(d[0]).intersection(*d[1:])
。否则你只会得到第一个列表。 - Alex@user3917838
这段代码简单易懂,但是需要一些强制类型转换来使它能够工作并给出一个列表作为结果。代码应该像这样:
list(reduce(set.intersection, [set(item) for item in d ]))
其中:
d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]
结果是:
[3, 4]
至少在Python 3.4版本中
您可以使用set.intersection(set1, set2, set3...)
获得任意数量集合的交集。因此,您只需要将列表转换为集合,然后按以下方式将它们传递给该方法:
d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]
set.intersection(*[set(x) for x in d])
结果:
{3, 4}
我认为reduce()
特别有用。事实上,numpy
文档建议使用reduce()
来求多个列表的交集:numpy.intersect1d reference
回答你的问题:
import numpy as np
from functools import reduce
# apply intersect1d to (a list of) multiple lists:
reduce(np.intersect1d, [list_1, list_2, ... list_n])
Lambda reduce.
from functools import reduce #you won't need this in Python 2
l=[[1, 2, 3, 4], [2, 3, 4], [3, 4, 5, 6, 7]]
reduce(set.intersection, [set(l_) for l_ in l])
TypeError: intersection() takes exactly one argument (2 given)
。 - Legendd
的长度可能为零,则set.intersection
函数将引发TypeError
异常。我建议捕获该异常并在这种退化情况下返回set()
(一个空集)而不是事先检查d
的长度,因为它可能是一个生成器。 - Aaron Robson