Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

set operation on a list of elements

I have a list containing thousands of sets similar to this:

set_list = [a, b, c, d]

each set in the list look something like this:

a = set([1, 2, 3, 4, 5])
b = set([4, 5, 6, 7, 7, 9])
c = set([1, 2, 6, 8, 10, 12, 45])
d = set([11, 3, 23, 3, 4, 44])

I would like to do the set operation: X-(YUZUAUB......etc) for every set in the list, for example, this would look something like this: after applying this operation on all elements in set_list the new elements look like this:

a = a.difference(b.union(c, d))
b = b.difference(c.union(a, d))
c = c.difference(d.union(b, a))
d = d.difference(a.union(c, b))

how do i accomplish this?

like image 678
ultron Avatar asked Jun 23 '18 13:06

ultron


2 Answers

One possibility is to make use of the multiset module to precompute the multiset union of all elements in set_list, like so:

from multiset import Multiset
union = sum(set_list, Multiset())
set_list = [s - (union - s) for s in set_list]

Here, union - s computes the Y ∪ Z ∪ A ∪ B... in your notation.

See Aran-Fey's answer for the same method implemented (more verbosely) using only the standard library.

like image 194
NPE Avatar answered Nov 03 '22 15:11

NPE


If I'm understanding correctly, you want the difference for each set and the union of the rest of the sets. I would use a loop and functools.reduce and operator.or_:

Setup

import functools
import operator

a = set([1, 2, 3, 4, 5])
b = set([4, 5, 6, 7, 7, 9])
c = set([1, 2, 6, 8, 10, 12, 45])
d = set([11, 3, 23, 3, 4, 44])
set_list = [a, b, c, d]

Loop and save results

# I don't know what you want to do with the results so
# I'll save them in a list...
results = [] 
for i in set_list:
    list_copy = list(set_list)
    list_copy.remove(i)
    r = i - functools.reduce(operator.or_, list_copy)
    results.append(r)

print(results)
# prints [set(), {9, 7}, {8, 10, 12, 45}, {11, 44, 23}]
like image 45
Tomas Farias Avatar answered Nov 03 '22 15:11

Tomas Farias