Take the intersection of an arbitrary number of lists in python

Suppose I have a list of lists of elements that are all the same (I will use int in this example)

 [range(100)[::4], range(100)[::3], range(100)[::2], range(100)[::1]] 

What would be a good and / or effective way to cross these lists (so that you get every item that is in each of the lists)? For example:

 [0, 12, 24, 36, 48, 60, 72, 84, 96] 
+3
python list algorithm intersection
source share
7 answers

Use sets that have an intersection method.

 >>> s = set() >>> s.add(4) >>> s.add(5) >>> s set([4, 5]) >>> t = set([2, 4, 9]) >>> s.intersection(t) set([4]) 

In your example, something like

 >>> data = [range(100)[::4], range(100)[::3], range(100)[::2], range(100)[::1]] >>> sets = map(set, data) >>> print set.intersection(*sets) set([0, 96, 36, 72, 12, 48, 84, 24, 60]) 
+7
source share

I think the set builtin should do the trick.

 >>> elements = [range(100)[::4], range(100)[::3], range(100)[::2], range(100)[::1]] >>> sets = map(set, elements) >>> result = list(reduce(lambda x, y: x & y, sets)) >>> print result [0, 96, 36, 72, 12, 48, 84, 24, 60] 
+4
source share

Convert them to settings and use the set.intersection method, reducing the list of lists:

 xs = [range(100)[::4], range(100)[::3], range(100)[::2], range(100)[::1]] reduce(set.intersection, [set(x) for x in xs]) 

reduce is a functional programming device that iterates through any iterative action and applies the function provided by the first two elements, then to the result and the next, and then to the result of this and the next, etc.

+3
source share

I will answer my question:

 lists = [range(100)[::4],range(100)[::3],range(100)[::2],range(100)[::1]] out = set(lists[0]) for l in lists[1:]: out = set(l).intersection(out) print out 

or

 print list(out) 
+1
source share

You can consider them as sets and use set.intersection() :

 lists = [range(100)[::4], range(100)[::3], range(100)[::2], range(100)[::1]] sets = [set(l) for l in lists] isect = reduce(lambda x,y: x.intersection(y), sets) 
0
source share
 l = [range(100)[::4], range(100)[::3], range(100)[::2], range(100)[::1]] l = [set(i) for i in l] intersect = l[0].intersection(l[1]) for i in l[2:]: intersect = intersect.intersection(i) 
0
source share

Here's the one-liner using the old old all() inline function:

 list(num for num in data[0] if all(num in range_ for range_ in data[1:])) 

Interestingly, this (I think) is more readable and faster than using set for large datasets.

0
source share

All Articles