Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code to find unique elements among lists / sets

Shaded area required

The above shaded area, according to Wolfram is supposed to represent:

 A XOR B XOR C XOR (A AND B AND C)

How to translate this into python code? The code must closely correlate to the set operations as provided in the above expression, at least that is the preference. The code must be generic enough to handle more more than 3 lists as well.

UPDATE: Seems like Wolfram is throwing up an erroneous venn diagram? Also, what we actually want is

(A XOR B XOR C) - (A AND B AND C)

and I am not able to represent that in Wolfram.

like image 750
lifebalance Avatar asked Jun 15 '26 00:06

lifebalance


2 Answers

Python supports sets (more about sets). For three lists it will be:

A = [1, 2, 3, 4]
B = [2, 3, 5, 6]
C = [3, 4, 5, 7]
As = set(A)
Bs = set(B)
Cs = set(C)

print((As ^ Bs ^ Cs) ^ (As & Bs & Cs))

For list of lists (this is wrong - all it does is XORing all sets, ANDing all sets and than XORing this two results - correct solution below):

import functools

def do_xor(s1, s2):
    return s1 ^ s2

def do_and(s1, s2):
    return s1 & s2

def do_task(list_of_lists):
    list_of_sets = list(map(set, list_of_lists))
    xors = functools.reduce(do_xor, list_of_sets)
    ands = functools.reduce(do_and, list_of_sets)
    return xors ^ ands

A = [1, 2, 3, 4]
B = [2, 3, 5, 6]
C = [3, 4, 5, 7]
D=[A, B, C]
print(do_task(D))

Correct solution:

import functools 

def do_or(s1, s2):
    return s1 | s2

def do_task2(list_of_lists):
    list_of_sets = list(map(set, list_of_lists))
    list_of_intersects = [X & Y for X in list_of_sets for Y in list_of_sets if X is not Y]
    intersects = functools.reduce(do_or, list_of_intersects)
    ors = functools.reduce(do_or, list_of_sets)
    return ors - intersects

lol33 = [
    [1, 2], 
    [3, 2], 
    [3], 
    [3, 2, 4]
    ]

print(do_task2(lol33)) # {1, 4}
like image 75
wpedrak Avatar answered Jun 16 '26 12:06

wpedrak


You can use operations & [intersection] and | [union] for your purpose. Data from @WPedrak.

A = {1, 2, 3, 4}
B = {2, 3, 5, 6}
C = {3, 4, 5, 7}

lst = [A, B, C]

result = (A | B | C) - ((A & B) | (A & C) | (B & C) | (A & B & C))

# {1, 6, 7}

Explanation

We take the union of all elements and subtract all intersections. See @WPedrak's solution for general case.

like image 45
jpp Avatar answered Jun 16 '26 13:06

jpp