11

Currently I am stuck trying to find the intersection of three sets. Now these sets are really lists that I am converting into sets, and then trying to find the intersection of.

Here's what I have so far:

for list1 in masterlist:
    list1 = thingList1
for list2 in masterlist:
    list2 = thingList2
for list3 in masterlist:
    list3 = thingList3

d3 = [set(thingList1), set(thingList2), set(thingList3)] 
setmatches c = set.intersection(*map(set,d3)) 
print setmatches

and I'm getting

set([]) 
Script terminated.

I know there's a much simpler and better way to do this, but I can't find one...

EDIT

Okay, here's what I have now.

setList=()
setList2=()
setList3=()

for list1 in masterlist:
    setList=list1
    for list2 in masterlist:
        setList2=list2
        for list3 in masterlist:
            setList3=list3



setmatches=set(setList) & set(setList2) & set(setList3)
print setmatches

Still doesn't give me what I'm looking for: which is the one match I ensured was in each list. It's giving me what looks like an addition of all the sets.

thephfactor
  • 181
  • 1
  • 2
  • 8
  • Your question seems to imply that the output is a problem, or unexpected. Is the output relevant to the question somehow? Are you sure there are any elements common to every list? – John Vinyard Oct 08 '12 at 21:44
  • 1
    What is the first part of your code supposed to do? The first three for loops appear to do nothing. – Andy Hayden Oct 08 '12 at 21:50
  • Ok, I'm dealing with a masterlist which consists of several sub-lists, each of which is a list of values. The part I am working on now is to change each sub-list into a set and intersect the sets. For the purposes of testing this program, I've ensured that there is one match. – thephfactor Oct 10 '12 at 18:28
  • OK everyone, big thank you for your help. It turns out that it was my stupid for loop that was messing everything up. All I needed to do was set(masterlist[1]) to get the set I wanted. – thephfactor Oct 10 '12 at 19:07

6 Answers6

38

I think you are simply looking for:

set(thingList1) & set(thingList2) & set(thingList3)

The ampersand is intersection in Python (and some other languages as well).

mjgpy3
  • 8,597
  • 5
  • 30
  • 51
4
set1 & set2 & set3

should work ... at least I think

>>> set((1,2,3)) & set((2,3,4)) & set((3,4,5))
set([3])
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
4
set.intersection(*map(set,d3)) 

Will actually work, though because d3 already contains sets you can just do:

set.intersection(*d3)

And, in fact, only the first one needs to be a set - the others can be any iterable, and intersection will setify them by itself.

The problem you're having doesn't seem to be in this code - rather,

for list1 in masterlist:
    list1 = thingList1

Won't actually put anything into thingList1. It is hard to tell without seeing what masterlist looks like, but you may want something like:

for list1 in masterlist:
   thingList1[:] = list1

print your three lists before you do the intersection to make sure they contain what you expect.

lvc
  • 34,233
  • 10
  • 73
  • 98
  • I tried your solution, it gave me a TypeError: descriptor 'intersection' requires a 'set' object but recieved a 'list' – thephfactor Oct 10 '12 at 18:46
  • @thephfactor because I typod it. Try the fixed version - `set.intersection(*d3)`. – lvc Oct 10 '12 at 23:02
3

This should do the trick:

reduce(lambda x,y: x&y, mysetlist)
RussellStewart
  • 5,293
  • 3
  • 26
  • 23
2

You need something like this:

frozenset(list1) & frozenset(list2) & frozenset(list1)
defuz
  • 26,721
  • 10
  • 38
  • 60
  • Those two lines are not functionally equivalent. The second is equivalent to the union of the three sets. – Dunes Oct 08 '12 at 21:48
2

A list of sets, you say?

In [1]: mylist = [ [1, 2, 3, 4], [3, 4, 5, 6, 7], [2, 3, 4, 5, 6] ]

In [2]: result = set(mylist[0])

In [3]: for item in mylist:
   ...:     result = result.intersection(item)
   ...:     
   ...:     

In [4]: result
Out[4]: set([3, 4])
Izkata
  • 8,961
  • 2
  • 40
  • 50