多列表的交叉?

我正在玩巨蟒,我能够得到两个列表的交集:

result = set(a).intersection(b)

现在,如果 d是一个包含 ab以及第三个元素 c的列表,那么是否有一个内置函数来查找 d中所有三个列表的交集?比如说,

d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]

那么结果应该是

[3,4]
84963 次浏览

for 2.4, you can just define an intersection function.

def intersect(*d):
sets = iter(map(set, d))
result = sets.next()
for s in sets:
result = result.intersection(s)
return result

for newer versions of python:

the intersection method takes an arbitrary amount of arguments

result = set(d[0]).intersection(*d[1:])

alternatively, you can intersect the first set with itself to avoid slicing the list and making a copy:

result = set(d[0]).intersection(*d)

I'm not really sure which would be more efficient and have a feeling that it would depend on the size of the d[0] and the size of the list unless python has an inbuilt check for it like

if s1 is s2:
return s1

in the intersection method.

>>> 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])
>>>
set.intersection(*map(set,d))

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

@user3917838

Nice and simple but needs some casting to make it work and give a list as a result. It should look like:

list(reduce(set.intersection, [set(item) for item in d ]))

where:

d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]

And result is:

[3, 4]

At least in Python 3.4

You can get the intersection of an arbitrary number sets using set.intersection(set1, set2, set3...). So you just need to convert your lists into sets and then pass them to this method as follows:

d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]
set.intersection(*[set(x) for x in d])

result:

{3, 4}

I find reduce() to be particularly useful. In fact, the numpy documents recommend using reduce() to intersect multiple lists: numpy.intersect1d reference

To answer your question:

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