Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find groupings of numeric subsets

Lets say I have these numeric sets

a = {1, 2, 3}
b = {2, 3, 4}
c = {1, 5}

I want to find all distinct numeric groupings of the sets. The result would be

{1}, {2, 3}, {4}, {5}

My naive approach, which doesn't work, is something like this:

data = [{1, 2, 3}, {2, 3, 4}, {1, 5}]
for i in range(1, 5):
    s = set.intersection(*[x for x in data if i in x])
    print(s)

Which returns

set([1])
set([2, 3])
set([2, 3])
set([2, 3, 4])

Which could be easily de-duplicated but doesn't give the expected result.

How can I get only the groupings of numbers that exist in subset of sets?

like image 464
Ian Fiddes Avatar asked Nov 24 '25 20:11

Ian Fiddes


1 Answers

Your code has two issues:

  • You stop at 5, but range doesn't include the stop so you don't check for 5.
  • If a value is only in one set you need to create a set that only contains that value. At least your expected result looks as if that's the desired behaviour.

So by fixing these issues the code would look like this:

data = [{1, 2, 3}, {2, 3, 4}, {1, 5}]
for i in range(1, 6):
    useful_sets = [x for x in data if i in x]
    if len(useful_sets) <= 1:
        print(set([i]))
    else:
        s = set.intersection(*useful_sets)
        print(s)

# prints:
# {1}
# {2, 3}
# {2, 3}
# {4}
# {5}

To get a complete (and not duplicated) result you could store them as frozensets in a set:

data = [{1, 2, 3}, {2, 3, 4}, {1, 5}]
res = set()
for i in range(1, 6):
    useful_sets = [x for x in data if i in x]
    if len(useful_sets) <= 1:
        res.add(frozenset([i]))
    else:
        s = set.intersection(*useful_sets)
        res.add(frozenset(s))

print(res)
# {frozenset({5}), frozenset({4}), frozenset({2, 3}), frozenset({1})}

Which (except for the ordering) should be exactly what you want.

like image 134
MSeifert Avatar answered Nov 27 '25 08:11

MSeifert