Legend
Legend

Reputation: 116820

Python -Intersection of multiple lists?

I am playing with python and am able to get the intersection of two lists:

result = set(a).intersection(b)

Now if d is a list containing a and b and a third element c, is there an built-in function for finding the intersection of all the three lists inside d? So for instance,

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

then the result should be

[3,4]

Upvotes: 100

Views: 104550

Answers (7)

abdelgha4
abdelgha4

Reputation: 431

Here is a general approach that works for any iterable of iterables and does not require making any copy of your data:

from typing import Iterable

def intersect[T](iterable_of_iterables: Iterable[Iterable[T]]) -> set[T]:
    iterator = iter(iterable_of_iterables)
    return set(next(iterator)).intersection(*iterator)

Usage:

>>> d = [[1,2,3,4], [2,3,4], [3,4,5,6,7]]
>>> intersect(d)
{3, 4}

Upvotes: 0

Bartek
Bartek

Reputation: 129

@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

Upvotes: 12

sgyzetrov
sgyzetrov

Reputation: 301

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

Upvotes: 4

aaronasterling
aaronasterling

Reputation: 71014

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

Upvotes: 65

A. John Callegari
A. John Callegari

Reputation: 149

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}

Upvotes: 12

user3917838
user3917838

Reputation:

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

Upvotes: 3

SingleNegationElimination
SingleNegationElimination

Reputation: 156158

set.intersection(*map(set,d))

Upvotes: 128

Related Questions