tags:

views:

151

answers:

3

I have the following list in Python:

[[1, 2], [3, 4], [4, 6], [2, 7], [3, 9]]

I want to group them into [[1,2,7],[3,4,6,9]]

My code to do this looks like this:

l=[[1, 2], [3, 4], [4, 6], [2, 7], [3, 9]]
lf=[]
for li in l:
    for lfi in lf:
        if lfi.intersection(set(li)):
            lfi=lfi.union(set(li))
            break
    else:
        lf.append(set(li))

lf is my final list. I do a loop over l and lf and when I find an intersection between an element from l and another from lf, I would like to merge them (union)

But I can't figure out why this is not working. The first to elements of the list l are being inserted with the append command, but the union is not working. My final list lf looks like [set([1, 2]), set([3, 4])]

It seems to be something pretty basic, but I'm not familiar with sets. I appreciate any help

Thanks

+5  A: 

The problem is here:

lfi=lfi.union(set(li))

You are not modifying the set. You are creating a new set which is then discarded. The original set is still in the lf array. Use update instead:

lfi.update(li)

This modifies the original set instead of creating a new one. The result after making this change:

[set([1, 2, 7]), set([9, 3, 4, 6])]
Mark Byers
Thank you very much. I though that the union behaved like an add, i.e., adding elements to the set, not creating a new one. I did not use add, because it have added the set itself , instead of its elements.
duduklein
+2  A: 

Here is another way to write the same thing
For sets,
& means intersection
|= means update

I have also used map(set,l) so that you are not recreating the same set over and over

l=[[1, 2], [3, 4], [4, 6], [2, 7], [3, 9]]
lf=[]
for li in map(set,l):
    for lfi in lf:
        if lfi & li:
            lfi |= li
            break
    else:
        lf.append(li)
gnibbler
Thansk also. I have to get used to optimizations like this
duduklein
A: 
l=[[1, 2], [3, 4], [4, 6], [2, 7], [3, 9]]
lf=[]
for li in l:
    for i, lfi in enumerate(lf):

        if lfi.intersection(set(li)):
            lfi=lfi.union(set(li))            
            lf[i] = lfi #You forgot to update the list
            break
    else:
        lf.append(set(li))
naivnomore